Search code examples
c#dockingz-order

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.


Solution

  • 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