How to Set Z-Order of a Control Using Winforms

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

Sample Image

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;

button under piturebox

        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;

Sample Image

Change Z-Index of a label control in code

turns out there's a BringToFront();

I was looking for bringToFront();



Related Topics



Leave a reply



Submit