当停靠控件可见时Z顺序更改

时间:2014-02-26 18:57:49

标签: c# docking z-order

我正在使用.NET Framework 4.0版的C#Winforms

我有一个面板,其中包含四个停靠在面板顶部的标签。中间的两个标签是隐藏的。

--- ---顶
标签一(可见)
标签二 - (不可见)
标签三(不可见)
标签四 - (可见)
--- ---底

单击带有以下代码的按钮时

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

标签显示了两个和三个但是它们的z顺序混合在一起,如下所示。

--- ---顶
标签一(可见)
标签(可见)
标签两个 - (可见)
标签四 - (可见)
--- ---底

为什么z顺序会发生变化,如何阻止这种情况发生。

我意识到我可以在点击事件中使用BringToFront()对所有标签进行重新排序,但这对于更复杂的对接安排感觉有点过分。

3 个答案:

答案 0 :(得分:5)

设置Control.Visible = True有时会更改Z顺序。它似乎取决于句柄的创建。

对我而言,这个(显然没有意义的)声明完美地帮助了我们:

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

它强制所有控件创建句柄。 之后control.visible = true不再更改Z顺序。

我从外部网站获得了该解决方案,现在转发到钓鱼网站。

答案 1 :(得分:4)

停靠顺序似乎与z顺序略有不同,使用SetChildIndex,您仍然必须按特定顺序分配每个标签的.Visible属性。我试图让lbl1和lbl4以不同的顺序出现,但他们总是保持在他们的位置。我认为你最好的选择就是按照你通常认为的“反向”顺序调用“中间”标签。

编辑:这是一种可以始终保持相同停靠顺序的方式,而不必担心始终按顺序设置每个标签的可见属性。只需创建此事件处理程序,您可以将其附加到每个停靠标签的VisibleChanged事件:

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);
}

向@Mark道具寻找SetChildIndex

答案 2 :(得分:0)

对于我的应用程序,用户可以在组合框中选择所需的建筑面板数量(最多5个),然后程序将为每个可以显示尺寸的面板显示一个编号面板,用户可以在其中输入尺寸(高度,宽度,厚度) )。创建了一个带有标题标签,面板编号,文本框和高度,宽度和厚度标签的面板。面板全部停靠在其包含面板中以控制布局。不幸的是,根据组合框中的选定值隐藏和显示面板会导致面板以半随机顺序显示。

private void cboNumberOfPanels_SelectedIndexChanged(object sender, EventArgs e)
{
    int numberOfPanels;
    int.TryParse(cboNumberOfPanels.SelectedItem.ToString(), out numberOfPanels);

    pnlPanelDimensions1.Visible = numberOfPanels >= 1;
    pnlPanelDimensions2.Visible = numberOfPanels >= 2;
    pnlPanelDimensions3.Visible = numberOfPanels >= 3;
    pnlPanelDimensions4.Visible = numberOfPanels >= 4;
    pnlPanelDimensions5.Visible = numberOfPanels >= 5;
}

我尝试使用上面的.SetChildIndex()建议,但在第二个选择上仍然遇到问题。例如,如果我选择1,则pnlPanelDimensions1将显示在正确的位置。如果然后选择3,则将首先显示pnlPanelDimensions2,然后显示pnlPanelDimensions3,最后显示pnlPanelDimensions1。在第二秒之后进行的所有后续更改中,所有内容都会正确显示。

我终于找到了一个在我的解决方案中每次都能正常工作的选项:

    int numberOfPanels;
    int.TryParse(cboNumberOfPanels.SelectedItem.ToString(), out numberOfPanels);

    pnlPanelDimensions1.Visible = numberOfPanels >= 1;
    pnlPanelDimensions1.BringToFront();
    pnlPanelDimensions2.Visible = numberOfPanels >= 2;
    pnlPanelDimensions2.BringToFront();
    pnlPanelDimensions3.Visible = numberOfPanels >= 3;
    pnlPanelDimensions3.BringToFront();
    pnlPanelDimensions4.Visible = numberOfPanels >= 4;
    pnlPanelDimensions4.BringToFront();
    pnlPanelDimensions5.Visible = numberOfPanels >= 5;
    pnlPanelDimensions5.BringToFront();