Click here to Skip to main content
Click here to Skip to main content

Control.Visible Might Not Return What You Expect

, 19 Nov 2009
Rate this:
Please Sign up or sign in to vote.
I encountered a curious issue while working on ImageListView. In the layout code of the control I have a check to determine whether to show the vertical scrollbar. If the scrollbar needs to be shown, the layout is recalculated since the display area will be smaller with the scrollbar shown...

I encountered a curious issue while working on ImageListView. In the layout code of the control, I have a check to determine whether to show the vertical scrollbar. If the scrollbar needs to be shown, the layout is recalculated since the display area will be smaller with the scrollbar shown. However, my layout code ended up being called infinitely resulting in a stack overflow eventually. Here is the relevant part of the layout code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public void UpdateLayout()
{
    // ...
    // ...
 
    // Maximum number of rows and columns that can be fully displayed
    int cols = displayBounds.Width / itemSize.Width;
    int rows = displayBounds.Height / itemSize.Height;
 
    // Check if we need the vertical scroll bar
    bool vScrollRequired = (cols * rows < items.Count);
    if (vScrollBar.Visible != vScrollRequired)
    {
        // Show the scrollbar
        vScrollBar.Visible = vScrollRequired;
 
        // Recalculate the layout
        UpdateLayout();
        return;
    }
 
    // ...
    // ...
}

The problem was with line 12 above. The Visible property of the scrollbar always returned false, if the layout code was called before the parent control is displayed. This is because -as I learned the hard way-, the getter of the Control.Visible property checks whether its parent control is visible. If not, it will return false regardless of what you set.

The solution was simple though. Keep a separate variable to track scrollbar’s visibility rather than relying on Control.Visible.

Here is what I do not get. If the Visible property actually means “the control is displayed on the screen” then why does it return true when the control is hidden under another control, or the control is moved beyond the client area of its parent?

ToolStripItem circumvents the issue by introducing the Available property. In the remarks section, MSDN says:

The Available property is different from the Visible property in that Available indicates whether the ToolStripItem is shown, while Visible indicates whether the ToolStripItem and its parent are shown. Setting either Available or Visible to true or false sets the other property to true or false.

This is what Control.Visible should be doing in the first place. To determine if the control is actually displayed on the screen, there should have been another read-only property (IsDisplayed perhaps?).

It may not be possible to fix Control.Visible since there are probably many applications relying on the current behavior. However, it should be possible to extend ToolStripItem.Available property to the Control class without causing many compatibility issues.

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0

About the Author

Ozgur Ozcitak

Turkey Turkey
No Biography provided

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 19 Nov 2009
Article Copyright 2009 by Ozgur Ozcitak
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid