Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Z Order Changing When Making Docked Controls Visible

I'm using C# Winforms with the .NET Framework version 4.0

I have a panel which contains four labels all docked to the top of the panel. The middle two labels are hidden.

---Top---
Label One (Visible)
Label Two - (NOT Visible)
Label Three (NOT Visible)
Label Four - (Visible)
---Bottom---

When a button with the code below is clicked

private void btnShowLabels_Click(object sender, EventArgs e)
{
    this.lblTwo.Visible = true;
    this.lblThree.Visible = true;
}

labels two and three appear but their z-order gets mixed up as shown below.

---Top---
Label One (Visible)
Label Three (Visible)
Label Two - (Visible)
Label Four - (Visible)
---Bottom---

Why is the z-order getting changed and how can I stop this happening.

I realise I could re-order all the labels using BringToFront() inside the click event but this feels like overkill especially for more complex docking arrangements.

like image 999
user1085489 Avatar asked Feb 26 '14 18:02

user1085489


2 Answers

Setting a Control.Visible = True changes the Z-order sometimes. It seems to depend to the handle creation.

For me this (obviously meaningless) statement helped perfectly:

foreach (Control ctrl in FlpDetails.Controls)
{
    IntPtr DummyHandle = ctrl.Handle;
}

It forces all controls to create the handles. After that control.visible = true doesn't change the Z-order anymore.

I got that solution from an external website, which now forwards to a fishing website.

like image 137
Ted Avatar answered Nov 18 '22 18:11

Ted


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

like image 5
user2320861 Avatar answered Nov 18 '22 18:11

user2320861