I have tried/researched for an entire day to set the location of Form2 called by a button click on Form1.
I allow the user to resize the forms and want Form2 to open at the same size and location of Form1 (wherever it is when they click the button).
This is what I've tried so far:`
app.hnow = this.Height;// size of form displayed now
app.wnow = this.Width;
app.module = 2; //indicates look up mode
lookprmtby lookby = new lookprmtby(this); instantiate Form2
app.hprev = lookby.ClientSize.Height; // gets original size of form being called
app.wprev = lookby.ClientSize.Width;
lookby.ClientSize = new Size(app.wnow, app.hnow);// set new size before show
lookby.WindowState = FormWindowState.Normal;
lookby.StartPosition = FormStartPosition.Manual;
// set lookby's location to same location as current form - i.e. left = 0 top = 174
lookby.Location = this.Location;// this does not work / lookby.location is 0,0 after this statement
lookby.Left = this.Location.X; // left and top do not work either-they evaluate to 0
lookby.Top = this.Location.Y;
lookby.Show();`
FYI, ClientSize is equivilent to the Size property. I'm using BinaryMission's ModernChromeWindow style as the basis for the majority of my forms.
Can anyone see the reason why the lookby.location property is evaluating to 0,0?
(VS 2019, c#)
Related
I am coding a VSTO com addin for Outlook. I created a form in the designer that displays as a dialog window when the user clicks a button on the ribbon. On that form is a RichTextBox that I use to display an RTF formatted message to the user. For the purposes of this question, let's call this "myRTFForm".
I also created a (completely unrelated) FormRegion that displays when a user views an email, either in the preview window or a new inspector window. Let's call this "myFormRegion".
If the user clicks the ribbon button to launch myRTFForm before viewing an email, everything is fine and the RichTextBox is visible on myRTFForm.
But, if the user clicks the ribbon button after viewing an email (thus displaying myFormRegion), myRTFForm displays, but with the RichTextBox hidden.
So for some reason, after myFormRegion is shown, the RichTextBox on (the completely unrelated) myRTFForm is getting set to hidden, and refuses to be set to visible no matter what I try. I even tried programmatically creating a new RichTextBox, and that ends up hidden as well.
If I instead use a regular text box (either through the designer or programmatically) that stays visible. So that is obviously a workaround -- but I'd really rather use the RichTextBox and its RTF formatting.
As you can see in the code below, I also did a sanity check to make sure I wasn't referencing the wrong form object -- by manually setting the RichTextBox to hidden, and sure enough, the RichTextBox comes up hidden even before viewing an email displaying myFormRegion.
One final thing -- I stepped through the code and watched the "Visible" property of the RichTextBox, and it remains true until the form's designer-generated code runs this line:
this.Controls.Add(this.groupBox1);
The weird thing is, the Visible property always turns false at this point, even when the RichTextBox actually displays properly before an email with myFormRegion is viewed.
I could not "step into" that line of code -- is there a way to do that? Perhaps with Resharper or some other tool?
If anyone has any insights into this weird behavior, I'd really appreciate it. Here is the code from the method that shows the myRTFForm dialog (the commented code shows all the things I've tried to get the RichTextBox to remain visible):
public DialogResult ShowMyDialog()
{
//_myForm.RichTextBox1.Rtf = ProcessedRTFText;
_myRichTextBox.Rtf = ProcessedRTFText;
int growIfMoreThan = 7; // Increase window height if more than this number of lines
int pixelsPerLine = 17; // Approx. number of pixels per line
int maxHeight = 800; // Max height of the window in pixels (draws a scrollbar at that point)
//int numLines = _myForm.RichTextBox1.Lines.Count();
int numLines = _myRichTextBox.Lines.Count();
if (numLines > growIfMoreThan)
{
int width = _myForm.Size.Width;
int height = _myForm.Size.Height;
int newHeight = height + ((numLines - growIfMoreThan) * pixelsPerLine);
if (newHeight > maxHeight)
{
newHeight = maxHeight;
}
_myForm.Size = new System.Drawing.Size(width, newHeight);
}
//_myRichTextBox.Hide(); // Sanity test -- works
//_myRichTextBox.Visible = false; // Sanity test -- works
// NONE OF THE FOLLOWING WORK AFTER FORMREGION DISPLAYED:
//_myForm.RichTextBox1.Show();
//_myRichTextBox.Show();
//_myForm.RichTextBox1.Visible = true;
//_myRichTextBox.Visible = true;
//_myForm.RichTextBox1.CreateControl();
//_myForm.RichTextBox1.BringToFront();
//_myForm.RichTextBox1.Update();
//_myForm.Update();
//RichTextBox testBox = new RichTextBox();
//testBox.AcceptsTab = true;
//testBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
//| System.Windows.Forms.AnchorStyles.Left)
//| System.Windows.Forms.AnchorStyles.Right)));
//testBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
//testBox.Font = new System.Drawing.Font("Segoe UI", 9.75F);
//testBox.ImeMode = System.Windows.Forms.ImeMode.Off;
//testBox.Location = new System.Drawing.Point(6, 23);
//testBox.Name = "richTextBox2";
//testBox.ReadOnly = true;
//testBox.Size = new System.Drawing.Size(698, 133);
//testBox.TabIndex = 11;
//testBox.TabStop = false;
//testBox.Text = "";
//testBox.Rtf = _processedRTFText;
//testBox.BringToFront();
//testBox.Update();
//testBox.Show();
//testBox.Visible = true;
//_myForm.Controls.Add(testBox);
//_myForm.GroupBox1.PerformLayout();
//_myForm.PerformLayout();
DialogResult result = _myForm.ShowDialog();
//testBox = null;
return result;
}
Lately I am working on this personal app, it's form is without border so the Exit Button, Minimize Button and Maximize button, as well as the option to resize and move the form have been custom added. The app contains several User Controls which perform different functions such as Login, a Control Panel for the app and so on. The issue here is that the User Controls, which are placed within a panel (Anchored properly, of course) in the main form are not resizing properly when the window is in a Maximized state.
To detail... the app starts at
this size and while it's manually resized in minimized state the controls have no issue inheriting it's parent's (the panel) size,
like this and this also works if the window is maximized while the control is visible, like this however if the window is already in a maximized state and I call the control with the designated button the control does not resize, it stays to it's minimum dimensions, like so.
At first I thought it may have something to do with the code that resizes the form so I removed everything and made the app with the default windows border and controls, basically set the border Property from none to sizable but that did nothing. Also I have tried accessing the User Control's parent (the panel) using this.Parent and then setting the width and height of the control with Width = this.Parent.Width and Height = this.Parent.Height but the parent returns null for some reason which I am yet to understand. Now, worth mentioning that those user controls are dynamically added (i.e Login loginForm = new Login();) to the panel every time the button is clicked and then Disposed once the control is left.
I looked all over Google for this but found nothing related and at this point I am out of options. I really want the app to be resizable and must resize properly so if anyone has any solutions I am open to anything.
Thanks anticipated.
Meanwhile, for Winforms, I may have an answer.. the key is to use the Resize event of your user control(s), see below. I tested this in Core 3.1 and Net 4.7, you can use an default designer.cs unit with an empty form. It has no issues with resize from maximized state.
My user control for the center app is named CenteredPanel and derived from Panel. Make sure you derive your user controls from Panel and call base() on the constructor, else the docking will not work properly.
Also, your question about parenting: it was not needed to use Parent below, but if you really need it, make sure you assign it !
public partial class Form1 : Form
{
private Panel panel1, panel2, panel3, panel4;
private CenteredPanel panelApp;
public Form1()
{
InitializeComponent();
this.panel1 = new System.Windows.Forms.Panel()
{ Parent = this, Dock = DockStyle.Fill };
this.panel2 = new System.Windows.Forms.Panel()
{ Parent = panel1, Dock = DockStyle.Left, Width = 120, BackColor = Color.FromArgb(60, 60, 60) };
this.panel3 = new System.Windows.Forms.Panel()
{ Parent = panel1, Dock = DockStyle.Fill };
this.panel4 = new System.Windows.Forms.Panel()
{ Parent = panel3, Dock = DockStyle.Top, Height = 60, BackColor = Color.FromArgb(60, 60, 60) };
this.panelApp = new WindowsFormsAppCore.CenteredPanel()
{ Parent = panel3, Dock = DockStyle.Fill, BackColor = Color.FromArgb(90, 90, 90) };
this.panel1.Controls.Add(this.panel3);
this.panel1.Controls.Add(this.panel2);
this.panel3.Controls.Add(this.panelApp);
this.panel3.Controls.Add(this.panel4);
this.Controls.Add(this.panel1);
}
}
public class CenteredPanel : Panel
{
Label label1, label2;
TextBox textbox1;
public CenteredPanel() : base()
{
this.Resize += new System.EventHandler(this.Resizer);
this.label1 = new System.Windows.Forms.Label()
{ Parent = this, AutoSize = true, Name = "label1", ForeColor =Color.White, Text = "Connectare Administrator" };
this.label2 = new System.Windows.Forms.Label()
{ Parent = this, AutoSize = true, Name = "label2", ForeColor = Color.White, Text = "Nume de utilizator" };
this.textbox1 = new System.Windows.Forms.TextBox()
{ Parent = this, AutoSize = true, Name = "textbox1", PasswordChar = '*', Text = "****" };
this.Controls.Add(this.label1);
this.Controls.Add(this.label2);
this.Controls.Add(this.textbox1);
}
public void Resizer(object sender, EventArgs e)
{
Point CenteringAnchor = new Point(Width / 2, Height / 2);
for (int i=0; i<Controls.Count; i++)
{
Control c = Controls[i];
// put your resizing rules here.. this is a very simple one
c.Location = new Point(CenteringAnchor.X - c.Width / 2, -40 + i * ((i == 1) ? 40 : 30) + CenteringAnchor.Y - c.Height / 2);
}
}
}
There is a DataGridView in my form. When I click a cell in this DataGridView, it would show a dialog.
Form_Para formPara = new Form_Para();
formPara.ShowDialog();
In general, I hope this dialog just within screen and below this cell.
If showing below this cell will out of screen, then change its position to above the cell.
I know I can get the size and position of dialog and range of screen to calculate new dialog position. However, is there a simpler method?
For example, when I set 'StartPosition' of dialogs as 'CenterParent'.
It will show in the center of parent form and within screen automatically. I don't need to calculate the new position for avoiding out of screen.
Thanks a lot.
Finally, I think setting 'StartPosition' of dialogs as 'CenterParent' is simpler.
And then change only the Location.Y for avoiding to cover current cell.
Point currCellPosTop, currCellBottom;
currCellPosTop = dataGridView1.GetCellDisplayRectangle(dataGridView1.CurrentCell.ColumnIndex, dataGridView1.CurrentCell.RowIndex, true).Location;
currCellPosTop = dataGridView1.PointToScreen(currCellPosTop);
currCellBottom = new Point(currCellPosTop.X, currCellPosTop.Y );
currCellBottom.Y += dataGridView1.CurrentCell.Size.Height;
Form_Para formPara = new Form_Para(currCellPosTop, currCellBottom);
formPara.StartPosition = FormStartPosition.CenterParent;
formPara.ShowDialog();
Dialog Form:
private Point _TriggerControlPosTop;
private Point _TriggerControlPosBottom;
public Form_Para(Point triggerControlPosTop, Point triggerControlPosBottom)
{
_TriggerControlPosTop = triggerControlPosTop;
_TriggerControlPosBottom = triggerControlPosBottom;
InitializeComponent();
}
And visible change event of dialog:
private void Form_Para_VisibleChanged(object sender, EventArgs e)
{
this.Location = new Point(this.Location.X, _TriggerControlPosBottom.Y);
if (_TriggerControlPosBottom.Y + this.Height > Screen.PrimaryScreen.Bounds.Height)
{
this.Location = new Point(this.Location.X, _TriggerControlPosTop.Y - this.Height);
}
}
I am trying to implement the following behaviour:
On a form there is a tabcontrol. On that tabcontrol there is a treeview. To prevent scrollbars appearing, I would like the form to change its size according to the contents of the treeview when displayed for the first time.
If the treeview has too many nodes to be displayed on the default size of the form, the form should change it's size so that there is no vertical scrollbar on the treeview (up to a maximum size allowed by the size of the screen).
What I need to know is, if it is possible to achieve this behaviour through the properties of the controls. I'm sure this can be achieved by calculating and settings the sizes of the elements programmatically, but I would like to know if there is a way to achieve this by settings like AutoSizeMode etc.
[UPDATE]
It's the first dialog a user of my application sees: It's a dialog to select the database to work with. It's a list of databases, with a tabcontrol, buttens etc. If the list is too long, scrollbars appear and a colleague of mine wants them to disappear.
Use the AutoSize and AutoSizeMode properties.
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.autosize.aspx
An example:
private void Form1_Load(object sender, EventArgs e)
{
// no smaller than design time size
this.MinimumSize = new System.Drawing.Size(this.Width, this.Height);
// no larger than screen size
this.MaximumSize = new System.Drawing.Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, (int)System.Windows.SystemParameters.PrimaryScreenHeight);
this.AutoSize = true;
this.AutoSizeMode = AutoSizeMode.GrowAndShrink;
// rest of your code here...
}
By using the various sizing properties (Dock, Anchor) or container controls (Panel, TableLayoutPanel, FlowLayoutPanel, etc.) you can only dictate the size from the outer control down to the inner controls. But there is nothing (working) within the .Net framework that allows to dictate the size of a container through the size of the child control. I also missed this a few times and tried the AutoSize property, but it never worked.
So all you can do is trying to get this stuff done manually, sorry.
From MSDN:
To maximize productivity, the Windows Forms Designer shadows the
AutoSize property for the Form class. At design time, the form
behaves as though the AutoSize property is set to false,
regardless of its actual setting. At runtime, no special
accommodation is made, and the AutoSize property is applied as
specified by the property setting.
This might be useful.
It resizes a new form to a user control, and then anchors the user control to the new form:
Form f = new Form();
MyUserControl muc = new MyUserControl();
f.ClientSize = muc.Size;
f.Controls.Add(muc);
muc.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
f.ShowDialog();
You could calculate the required height of the TreeView, by figuring out the height of a node, multiplying it by the number of nodes, then setting the form's MinimumSize property accordingly.
// assuming the treeview is populated!
nodeHeight = treeview1.Nodes[0].Bounds.Height;
this.MaximumSize = new Size(someMaximumWidth, someMaximumHeight);
int requiredFormHeight = (treeView1.GetNodeCount(true) * nodeHeight);
this.MinimumSize = new Size(this.Width, requiredFormHeight);
NB. This assumes though that the treeview1 is the only control on the form. When setting the requiredFormHeight variable you'll need to allow for other controls and height requirements surrounding the treeview, such as the tabcontrol you mentioned.
(I would however agree with #jgauffin and assess the rationale behind the requirement to resize a form everytime it loads without the user's consent - maybe let the user position and size the form and remember that instead??)
This technique solved my problem:
In parent form:
frmEmployee frm = new frmEmployee();
frm.MdiParent = this;
frm.Dock = DockStyle.Fill;
frm.Show();
In the child form (Load event):
this.WindowState = FormWindowState.Maximized;
If you trying to fit the content according to the forms than the following will help. It helps me while I was trying to fit the content on the form to fit when ever the forms were resized.
this.contents.Size = new Size(this.ClientRectangle.Width,
this.ClientRectangle.Height);
I User this Code in my project, Useful for me.
private void Form1_Resize(object sender, EventArgs e)
{
int w = MainPanel.Width; // you can use form.width when you don't use panels
w = (w - 120)/4; // 120 because set 15px for each side of panels
// and put panels in FlowLayoutPanel
// 4 because i have 4 panel boxes
panel1.Width = w;
panel2.Width = w;
panel3.Width = w;
panel4.Width = w;
}
I used this code and it works just fine
const int margin = 5;
Rectangle rect = new Rectangle(
Screen.PrimaryScreen.WorkingArea.X + margin,
Screen.PrimaryScreen.WorkingArea.Y + margin,
Screen.PrimaryScreen.WorkingArea.Width - 2 * margin,
Screen.PrimaryScreen.WorkingArea.Height - 2 * (margin - 7));
this.Bounds = rect;
I want to show a new form in the same window from where it was invoked.
I know a way to show this form on PrimaryScreen or Virtual Screen by code similar to as below:
MyForm.Location = Screen.PrimaryScreen.Bounds.Location;
But i want to show it on current screen.
Is there a way to find out and show it on current screen?
I have done something like this to show my form centered to the current screen:
var screen = Screen.FromPoint(Cursor.Position);
myForm.StartPosition = FormStartPosition.Manual;
myForm.Left = screen.Bounds.Left + screen.Bounds.Width / 2 - myForm.Width / 2;
myForm.Top = screen.Bounds.Top + screen.Bounds.Height / 2 - myForm.Height / 2;
You can use the same technique, but instead of using the PrimaryScreen, grab the screen using Screen.FromPoint and Cursor.Position:
Screen screen = Screen.FromPoint(Cursor.Position);
MyForm.Location = screen.Bounds.Location;
It sounds like you aren't setting the StartPosition to Manual.
If you already have a parent form and want to open a new form on the same screen, give the ShowDialog method a reference to the parent form: newForm.ShowDialog(this); Without owner parameter ("this") the new form may open on the main screen even when your parent form is on another screen.
Click on the Form in design mode.
Change the StartPosition property to CenterScreen .
This should open up the form on the active screen. Refer
this for more values of StartPosition.
I know this is late, but still, post my answer hope that it will help someone else. After several tries, I got this work with 3 monitors
var currentScreen = Screen.FromControl(this);
if (!currentScreen.Primary)
{
var hCenter = currentScreen.Bounds.Left + (((currentScreen.Bounds.Right - currentScreen.Bounds.Left) / 2) - ((Width) / 2));
var vCenter = (currentScreen.Bounds.Bottom / 2) - ((Height) / 2);
StartPosition = FormStartPosition.Manual;
Location = new Point(hCenter, vCenter);
}
else
{
CenterToScreen();
}
Many years later, but no item was marked as the appropriate answer and I combined two comments to get it working (namely from Reed Copsey and Jason).
I haven't tried any of the other methods described, since this worked without problem and got the Form to open on the monitor my cursor is at, as intended.
Here's my working code:
Screen screen = Screen.FromPoint(Cursor.Position);
Application.Run(new Form1()
{
StartPosition = FormStartPosition.Manual, //Summary in VS actually mentions this as needed to make use of Location
Location = screen.Bounds.Location,
WindowState = FormWindowState.Maximized
});