How to set Z-order of a Control using WinForms
Call the GetChildIndex
and SetChildIndex
methods of the parent's Controls
collection.
Is there any way of setting the Z-order of controls on a panel to always be on top when a new control is added?
You can use the BringToFront()
method, available to every Winform control:
controlName.BringToFront();
This brings the control controlName
to the top of the z-order, forcing it to have a z-order of 0.
Winform controls event when z order changed
Changing the ChildIndex will trigger a Layout Event on the control that is parent to the child control. Of course this assumes that SuspendLayout has not been called on the parent control.
You can filter the event by checking the LayoutEventArgs.AffectedProperty Property (a string) to see if it is equal to "ChildIndex". To determine which control triggered the event, check the LayoutEventArgs.AffectedControl Property
Z-Order of Forms in WinForms
Try this in your top form.
private List<Form> subForms;
private bool minimized = false;
public TopForm()
{
InitializeComponent();
subForms = new List<Form>();
subForms.Add(new SubForm(1));
subForms.Add(new SubForm(2));
subForms.Add(new SubForm(3));
subForms.Add(new SubForm(4));
subForms.Add(new SubForm(5));
foreach (Form f in subForms)
{
f.Show();
}
BringToFront();
Resize += OnResize;
}
/// <summary>
/// Detects a resize event and handles it according to window state.
/// </summary>
/// <param name="sender">Top form</param>
/// <param name="args">Unused</param>
private void OnResize(object sender, EventArgs args)
{
switch (WindowState)
{
case FormWindowState.Normal:
if (minimized)
{
minimized = false;
OnRestore();
}
break;
case FormWindowState.Minimized:
minimized = true;
OnMinimize();
break;
}
}
/// <summary>
/// Minimize all sub forms
/// </summary>
public void OnMinimize()
{
foreach (Form form in subForms)
{
form.WindowState = FormWindowState.Minimized;
}
}
/// <summary>
/// Restore all forms and bring them to the front, with this main form on top.
/// </summary>
public void OnRestore()
{
foreach (Form form in subForms)
{
form.WindowState = FormWindowState.Normal;
form.BringToFront();
}
BringToFront();
}
Z-Index in winforms
WinForms has a z-order, but you can't access it as a number. Instead, every control has a BringToFront
method and a SendToBack
method, which move the control to the top of the z-order or to the bottom, respectively.
Not sure exactly why it was exposed this way, although you rarely encounter situations where either BringToFront or SendToBack don't provide what you need.
Update: I'm wrong, you can access the z-order directly via a method on the control's container's Controls
collection. Here's a simple method that wraps it:
public void SetControlZOrder(Control ctrl, int z)
{
ctrl.Parent.Controls.SetChildIndex(ctrl, z);
}
I'm guessing they encapsulated this in BringToFront
and SendToBack
just to keep everything simple and easy to use. I applaud.
Update 2: I interpreted your comments to a different answer here to mean that you want to be able to take a control that is inside a panel and larger than the panel (so that part of it is hidden) and make it so that the control is in front of the panel and larger than it (so that you see the whole control).
You can do this by removing the control from the panel, shifting its position by the original panel's position, and adding it to the form's controls:
panel1.Controls.Remove(button1);
button1.Left += panel1.Left;
button1.Top += panel1.Top;
this.Controls.Add(button1);
The Left and Top shifts are necessary because the button's position was originally relative to the panel, and will now be relative to the form. The shifts keep it in the original virtual position, so it appears to come out of the panel.
You would then have to deal with putting it back in the panel, which is just a reverse of the above code.
Z Order Changing When Making Docked Controls Visible
Docking order seems to be a little different from z-order, and with SetChildIndex you'll still have to assign each label's .Visible
property in a certain order. I've played around with this trying to get lbl1 and lbl4 to appear in different order but they always stay in their position. I think your best bet is to just call the "middle" labels in "reverse" order of what you would normally think.
EDIT: Here's a way you can always keep the same dock order while not having to worry about setting each label's visible property in order all the time. Just create this event handler that you can attach to each docked label's VisibleChanged
event:
void GenericDockedLabel_VisibleChanged(object sender, EventArgs e)
{
this.Controls.SetChildIndex(lbl1, 3);
this.Controls.SetChildIndex(lbl2, 2);
this.Controls.SetChildIndex(lbl3, 1);
this.Controls.SetChildIndex(lbl4, 0);
}
Props to @Mark for the finding the SetChildIndex
Change Z order of the control on edit mode in VS winform
If i understand you correctly, it should just be a case of
Rightclick -> Bring to Front
An image for specificity
C# - Reordering controls by z-index in Panel
I fount this to be an issue with the order of the controls in the panel in the design.cs
Remove the controls from the panel and add them in the correct order.
this.panel1.Controls.Add(this.pictureBox1);
this.panel1.Controls.Add(this.button1);
this.panel1.Location = new System.Drawing.Point(12, 12);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(260, 238);
this.panel1.TabIndex = 0;
this.panel1.Controls.Add(this.button1);
this.panel1.Controls.Add(this.pictureBox1);
this.panel1.Location = new System.Drawing.Point(12, 12);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(260, 238);
this.panel1.TabIndex = 0;
Change Z-Index of a label control in code
turns out there's a BringToFront();
I was looking for bringToFront();
Related Topics
Incorrect List Model Binding Indices When Using HTML Helpers
Rowspan Does Not Work in Itextsharp
Debugging Automatic Properties
How to Convert an Object to a Byte Array in C#
How to Add Js and CSS Files in ASP.NET Core
Style Bundling Not Working After Iis Deployment (MVC 4)
How to Extract Data from a Datatable
Cross Platform (PHP to C# .Net) Encryption/Decryption with Rijndael
When Do We Need to Set Processstartinfo.Useshellexecute to True
Implicit VS Explicit Interface Implementation
Query an Xdocument for Elements by Name at Any Depth
How to Marshal a Struct That Contains a Variable-Sized Array to C#
How to Find All Possible Subsets of a Given Array
Copy Constructor Versus Clone()
How to Determine the Standard Deviation (Stddev) of a Set of Values
Difference Between Await and Continuewith
Is There an Alternative to String.Replace That Is Case-Insensitive