How do I determine visibility of a control?
Asked Answered
A

3

12

I have a TabControl that contains several tabs. Each tab has one UserControl on it. I would like to check the visibility of a control x on UserControl A from UserControl B. I figured that doing x.Visible from UserControl B would be good enough. As it turns out, it was displaying false in the debugger even though I set it explicitly to true and it was never changed. Then I read on MSDN for Control.Visible that:

Even if Visible is set to true, the control might not be visible to the user if it is obscured behind other controls.

So much to my surprise, that will not work. Now I'm wondering how I can tell if the control x is visible from a different UserControl. I would like to avoid using a boolean if possible. Has anyone run into this and found a solution?

Note: It also appears that Control.IsAccessible is false in this situation.

Audraaudras answered 12/5, 2011 at 15:20 Comment(7)
Did you try ascending in the container hierarchy and determining not visible if any of them isn't visible?Humming
Yes, all the parent controls all the way up have the Visible property set to false.Audraaudras
So you are not visible, am I correct?Humming
The control itself is Visible, just not visible to the user.Audraaudras
Well, my point is - control is TRULY visible if it and all its containers are visible.Humming
I'm not questioning the behavior of the Visible property, my question is, how can I tell if the control was visible while on a differnt control.Audraaudras
This sounds like a symptom of what is discussed in this later Q&A: https://mcmap.net/q/612242/-c-usercontrol-visible-property-not-changingDumps
P
9

Unfortunately the control doesn't provide anything public that will allow you to check this.

One possibility would be to set something in the controls 'Tag' property. The tag’s purpose is to associate user data with the control. So it can be anything not just a boolean.

Here is the Tag property doc

If you really want the brute force way, you can use Reflection, basically calling 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 }));
}
Plasmo answered 12/5, 2011 at 15:41 Comment(1)
+1 Good find. Looks like nobugz (aka Hans Passant) posted something similar here: social.msdn.microsoft.com/Forums/en/winforms/thread/…. Thanks for the answer!Audraaudras
B
1

Please try this:

bool ControlIsReallyVisible(Control C)
{
    if (C.Parent == null) return C.Visible;
    else return (C.Visible && ControlIsReallyVisible(C.Parent));
}
Bergeman answered 12/5, 2011 at 19:54 Comment(2)
This solution did not work for me. Always returns true.Baffle
IMHO, This can't help. OP reports that x.Visible is false. In that case, the result of x.Visible && any-other-code will still be false.Dumps
T
0

I'm using this code not only checking all the ancestors visible and also who is the root control. Checking a root is needed when the control is not added on the Mainform.

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;
    }
}
Trouper answered 5/7, 2018 at 6:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.