如何确定控件的可见性?

Posted

技术标签:

【中文标题】如何确定控件的可见性?【英文标题】:How do I determine visibility of a control? 【发布时间】:2011-08-24 05:35:57 【问题描述】:

我有一个包含多个选项卡的TabControl。每个选项卡上都有一个UserControl。我想从UserControl B 中检查UserControl A 上的控件x 的可见性。我认为从UserControl Bx.Visible 就足够了。事实证明,它在调试器中显示false,即使我将它明确设置为true 并且它从未更改过。然后我在 MSDN 上看到 Control.Visible :

即使 Visible 设置为 true,如果控件隐藏在其他控件后面,用户也可能看不到该控件。

令我惊讶的是,这行不通。现在我想知道如何判断控件x 是否从不同的UserControl 可见。如果可能,我想避免使用布尔值。有没有人遇到过这个问题并找到了解决方案?

注意:在这种情况下,Control.IsAccessible 似乎也是假的。

【问题讨论】:

您是否尝试在容器层次结构中升序并确定如果其中任何一个不可见则不可见? 是的,所有的父控件都将Visible 属性设置为false 所以你不可见,对吗? 控件本身是可见的,只是对用户不可见。 好吧,我的意思是 - 如果控件及其所有容器都可见,那么控件是真正可见的。 【参考方案1】:

不幸的是,该控件没有提供任何可以让您检查的公开内容。

一种可能性是在控件的“标签”属性中设置一些内容。标签的目的是将用户数据与控件相关联。所以它可以是任何东西,而不仅仅是一个布尔值。

Here is the Tag property doc

如果你真的想要蛮力的方式,你可以使用反射,基本上是调用GetState(2):

public static bool WouldBeVisible(Control ctl) 

      // Returns true if the control would be visible if container is visible
      MethodInfo mi = ctl.GetType().GetMethod("GetState", BindingFlags.Instance | BindingFlags.NonPublic);
      if (mi == null) return ctl.Visible;
      return (bool)(mi.Invoke(ctl, new object[]  2 ));

【讨论】:

+1 很好的发现。看起来 nobugz(又名 Hans Passant)在这里发布了类似的内容:social.msdn.microsoft.com/Forums/en/winforms/thread/…。感谢您的回答!【参考方案2】:

请试试这个:

bool ControlIsReallyVisible(Control C)

    if (C.Parent == null) return C.Visible;
    else return (C.Visible && ControlIsReallyVisible(C.Parent));

【讨论】:

这个解决方案对我不起作用。总是返回 true。 恕我直言,这无济于事。 OP 报告 x.Visiblefalse。在这种情况下,x.Visible && any-other-code 的结果仍然是false【参考方案3】:

我使用这段代码不仅检查所有可见的祖先,而且检查谁是根控件。主窗体上未添加控件时,需要检查根目录。

public static class StratoControlExtension

    public static bool TruelyVisible(this Control control, Control expected_root)
    
        if (control.Parent == null)  return control == expected_root && control.Visible; 
        return control.Parent.TruelyVisible(expected_root) && control.Visible;
    

【讨论】:

以上是关于如何确定控件的可见性?的主要内容,如果未能解决你的问题,请参考以下文章

Silverlight 4:如何切换控件可见性

如何检测控件的可见性?

如何识别控件的可见性是不是被用户更改?

如何从 MaterialDesignXamlToolkit 中删除 ComboBox 控件中的装饰器可见性?

如何在自定义 wpf 控件上绑定数据网格列的可见性?

全网最优雅安卓控件可见性检测