Click here to Skip to main content
Click here to Skip to main content
Go to top

Extension method to determine if control is visible in complex hierarchy

, 25 Dec 2011
Rate this:
Please Sign up or sign in to vote.
Determine visibility in complex (or composite) form
This tip is compliment to the tip at: Extension method to make a control visible in complex hierarchy[^]
 
Consider the scenario where you have multiple nested tabcontrols:
 
TabControlMain
  TabPageMainOne
    TabControlSubOne
      TabPageSubOne
      TabPageSubTwo
           MyControl
  TabPageMainTwo
    TabControlMoreSubs
      TabPageMoreSubsOne
      TabPageMoreSubsTwo
 
The common (naive) approach to determining whether MyControl is currently visible on screen is either cumbersome or error prone:
 
   // See if MyControl is visible, if it is, I should refresh it.
   bool isVisible = TabControlSubOne.ActivePage == TabPageSubOne
                    && TabControlMain.ActivePage == TabPageMainOne;
 
This kind of works, until the screen is turned into a usercontrol and placed on a third TabControl. Now there is another control to consider, but your code was not designed to do so. This is a common scenario in dynamically composed screens.
 
Another problem with this method occurs within the screen itself and has to do with maintainability. What happens if we redesign the screen and decide that MyControl should be moved to TabPageMoreSubsTwo? Now our test is invalid, but because the code itself is not obviously wrong, we might not discover the problem until it is too late (production).
 
So obviously, this is less than desirable. What went wrong?
Let's return to the original problem and the way it is implemented. The question asked was 'Is My Control Visible' but it was implemented as: 'Have some tabcontrols the correct active page property'. The problem with the implementation is the word 'some' as I have shown above that checking 'some' might not be enough, or even be the wrong ones.
 
To solve the problem, we should implement this as 'Have ALL tabcontrols the correct active page property'? which is what this extension method does.
 
Usage:
   // See if MyControl is visible, if it is, I should refresh it.
   bool isVisible = MyControl.IsMyControlVisible(); 
 
This extension method has a nice benefit that we abstract away the 'how' and only the 'what' of the source code remains. +1 For readability.
 
/// <summary>
/// Checks to see whether the provided subject is visible in the tabpage hierarchy of a form.
/// It navigates up the parent-hierarchy and when it encounters a tabControl, checks to see whether
/// the current parent is actually the active tabpage. When the result of this check is false, 
/// the functions exits with false as a result.
/// Supports TabControls and Infragistics.UltraTabPageControl
/// </summary>
/// <param name="subject">The subject.</param>
/// <returns>
/// True is all tabpages where the active control.
/// </returns>
public static bool IsMyControlVisible(this Control subject)
{
    if ((subject == null) || (subject.Parent == null))
    {
      return false;
    }
	 
    Control testSubject = subject;
    TabControl parentPageControl = null;
    UltraTabPageControl aPage = null;
    Control testSubject = subject;
    while (testSubject != null)
    {
        TabPage asTabPage = (testSubject as TabPage);
        if (asTabPage == null)
        {
            UltraTabPageControl asUltraTabPage = testSubject as UltraTabPageControl;
            if (asUltraTabPage != null)
            {
                if (asUltraTabPage.TabControl == null)
                {
                    return false;
                }
                if (asUltraTabPage.TabControl.SelectedTab != asUltraTabPage.Tab)
                {
                    return false;
                }
            }
        }
        else
        {
            TabControl parentPageControl = asTabPage.Parent as TabControl;
            if (parentPageControl == null)
            {
                return false;
            }
            if (parentPageControl.SelectedTab != testSubject)
            {
                return false;
            }
            testSubject = parentPageControl;
        }
 
        if (testSubject != null)
        {
            testSubject = testSubject.Parent;
        }
    }
    return true;
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Kabwla.Phone
Software Developer (Senior)
Netherlands Netherlands
Doing that 'computer thing' ever since the C64.
 
Sometimes I feel that being a programmer is much like being a doctor: You just have to know everything and if you don't, something dies.
 
Either being an appliction or a patient.
Oddly enough, more people care about the death of their application, than the massacre op people...

Comments and Discussions

 
Generalif (testSubject is UltraTabPageControl) { aPage = testSu... PinmvpLuc Pattyn27-Nov-11 22:54 
GeneralRe: You are very right and I should/will change the code. Howeve... PinmemberKabwla.Phone27-Nov-11 23:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140916.1 | Last Updated 25 Dec 2011
Article Copyright 2011 by Kabwla.Phone
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid