【问题标题】:Z Order Changing When Making Docked Controls Visible使停靠控件可见时 Z 顺序更改
【发布时间】:2014-02-26 18:57:49
【问题描述】:

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

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

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

当点击带有以下代码的按钮时

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

标签 2 和 3 出现了,但它们的 z 顺序混淆了,如下所示。

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

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

我意识到我可以在 click 事件中使用 BringToFront() 重新排序所有标签,但这感觉有点矫枉过正,尤其是对于更复杂的对接安排。

【问题讨论】:

  • 您是否尝试过切换.visible 呼叫的顺序?
  • 我在研究您的问题时遇到了this post。您是否尝试过使用父级的Controls 集合中的SetChildIndex 方法设置每个标签的索引?

标签: c# docking z-order


【解决方案1】:

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

对我来说,这个(显然毫无意义的)陈述非常有用:

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

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

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

【讨论】:

  • 感觉有点骇人听闻,但绝对适合我。
  • 您的链接现在重定向到某个钓鱼网站。如果您能找到替代来源,那就太好了
【解决方案2】:

停靠顺序似乎与 z-order 有点不同,使用 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 的道具

【讨论】:

    【解决方案3】:

    对于我的应用程序,用户可以在组合框中选择他们想要的建筑面板数量(最多 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();
    

    【讨论】:

      猜你喜欢
      • 2020-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 2011-02-06
      • 1970-01-01
      相关资源
      最近更新 更多