I hate the Control.Visible property. It tries to do two things instead of one and so broken.
Imagine you have a Panel somewhere in your application and you add a Button onto that Panel. Set the Button.Visible to be False and then back again to True. It works exactly as you would expect by hiding the control and then displaying it again.
Now move up a level and try setting the Panel.Visible to be False so the whole Panel, including the contained Button, is hidden away. Whilst hidden try asking for the Button.Visible value and you will see it comes back with False! This is bad because it’s clearly returning a value indicating if the Button is currently visible rather than a value indicating if the Button would like to be visible. There is a big difference between those two semantics.
This problem becomes evident when you want to create your own custom layout panel. Your custom control will need to scan the set of child controls and decide how to arrange them. To make your control behave itself you want to honor the visible setting of child controls. But your stuck because asking a child control for its visible property will not always give the correct answer. If your control performs a layout when it happens to be hidden then all the children will automatically say they want to be hidden as well. Not because they really want to be invisible but purely because at the time the child control was asked the parent chain had a control that was not currently visible.
What we really need is two properties. The Control.Visible should act as an indication of the visible state the control would like to have. So the ‘get’ should return the same value as the last ‘set’. Then a new property called Control.CurrentlyVisible that returns if the control is currently visible based on the state of all the parent controls up the chain of controls up to and including the owning Form.
This is something I have had to get around for the KryptonNavigator and KryptonWorkspace controls because they suffer from exactly this issue. They both have child collections of controls and need to honor the visible state of those controls. Luckily I can get around it because they can only have child controls of a type I have defined. So I can easily add the extra properties needed to those defined types. But this would fail if my collection could take any arbitrary control and not just my own types.