【问题标题】:Control not visible after toggling visibility recursively?递归切换可见性后控件不可见?
【发布时间】:2019-04-30 12:45:01
【问题描述】:

快速笔记

我已尝试尽可能详尽地回答我的问题,但您可能仍需要进一步澄清;如果发生这种情况,请随时评论您的疑虑,我会更新帖子以尽我所能回答。


昨天我在表单上切换控件时遇到了一个相当奇怪的问题。我在FormShown 上有一段时间的加载,除了加载显示之外的所有控件都应该被隐藏。该切换用于关闭除加载显示之外的所有内容的可见性,但加载完成后,只有部分控件可见。

我单步执行了将所有内容变为可见的代码,并确保所有内容都确实设置为Visible = true。我认为这可能与控件上的 Dock 属性有关,或者可能与 TabIndex 或类似的属性有关,但我无法追踪潜在问题。

这是我用来切换控件可见性的代码:

private void ToggleAllControlVisibility() {
    foreach (Control c in Controls)
        ToggleControlVisibility(c);
}
private void ToggleControlVisibility(Control c) {
    if (c.Name == "loadingContainer")
        return;

    if (!(c is SplitContainer || c is SplitterPanel))
        c.Visible = !c.Visible;

    foreach (Control child in c.Controls)
        ToggleControlVisibility(child);
}

这是一个递归切换,其中所有子控件也会被切换。 ToggleAllControlVisibility 方法在加载开始前调用,加载完成后再次调用。


更详细的外观

既然您知道了问题所在,那么我知道某些控件特别不会显示(至少它们应该显示的方式)。以如下控制树为例:

  • pTimePanel(面板)
    • timeSlider (TrackBar)
    • lblStartTime(标签)
    • lblStopTime(标签)

在上面的控件中,只有pTimePanel 实际显示在前台。我相信它的子控件可能会以某种方式显示在它后面,因为当我逐步执行代码并到达lblStartTime 控件时,我可以简要地看到标签的轮廓(无内容),然后当它移动到下一个控件时它是走了。 timeSlider 控件似乎没有显示相同的行为,但它确实返回到 Visible = true

从窗体到上述控件的完整树(带有停靠属性)如下:

splitContainer : Dock-Fill
    panel1 (SplitterPanel)
        loadingPanel (Panel) : Dock-Fill
        pTimePanel (Panel) : Dock-Bottom
            pTimeLabels (Panel) : Dock-Bottom
                lblStartTime (Label) : Dock-Left
                lblStopTime (Label) : Dock-Right
            timeSlider (TrackBar) : Dock-Fill

注意事项

其中一些可能不如其他有用,但当我想到可能有助于澄清发生了什么的事情时,我会在此处添加它们。

  • 在任一方向切换可见性时,loadingPanel 上的 Resize 事件将引发。

问题

可能会发生什么使这种奇怪的行为成为可能?

【问题讨论】:

  • 你确定timeSliderpTimePanel 里面,而不是躲在timeSlider 后面吗?
  • 对于这类问题,我经常发现尝试在一个非常简单的新项目中重新创建它会有所帮助。要么从零开始构建真正的代码,要么从真正的代码的副本开始并删减内容。如果你能做到这一点,并发布示例,人们就会为你调试它。
  • @RobinBennett 这是一个非常好的主意,我考虑过重建表单以确保一切都在它应该在的位置,然后再试一次,但我想我会看看是否有其他人遇到过一个类似的问题,因为我从未见过更简单的表格。我在想,也许我只是按错误的顺序添加了一些东西。
  • 可以切换父控件的可见性来切换其子控件的可见性吗?在这种情况下,我不会切换,而是将可见性显式设置为 truefalse
  • 也许不递归地应用切换会有所帮助,而是只切换顶级控件的可见性,loadingContainer 除外。我也会测试c == loadingContainer。这比依赖名称更安全。

标签: c# winforms controls toggle visibility


【解决方案1】:

事实证明,这与控件添加到表单的顺序有关。由于一些复制和粘贴控件,不久前事情最终以不正确的顺序结束。我必须从头开始重建表单才能使任何切换都能真正起作用。重建表单后,所有可用的切换选项都开始按我预期的方式工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-08
    • 1970-01-01
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多