Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / All-Topics

Control.Visible Might Not Return What You Expect

0.00/5 (No votes)
19 Nov 2009Apache2 min read 11.9K  
Control.Visible might not return what you expect

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.

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

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