This tip is compliment to the tip at: Extension method to determine if control is 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 make MyControl
visible on screen is cumbersome and error prone:
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 the code does not actually show the control, but, because there is a huge 'disconnect' between what we are trying to do and how we are doing it, we might not discover the problem until late.
As stated, the big problem here is the huge difference between what we are trying to do and how we are doing it. What we really need is a method that follows the Parent-hierarchy up to the Form and 'fix' all TabControl
s (or equivalent) to make the control visible. That is what this extension does.
Usage:
MyControl.TabSwitchToControl();
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.
public static void LogError(this Exception ex)
{
}
public static bool TabSwitchToControl(this Control subject, bool shouldActivateControl = false)
{
bool result = true;
if (subject == null)
{
result = false;
}
else
{
List<control> tabSwitches = new List<control>();
#region Build a list of tabswitched to perform to make the control visible
var testSubject = subject;
while (testSubject != null)
{
var asTabPage = (testSubject as TabPage);
if (asTabPage != null)
{
var asTabControl = asTabPage.Parent as TabControl;
if (asTabControl != null)
{
tabSwitches.Insert(0, testSubject);
testSubject = asTabControl;
}
}
else
{
var asUltraPage = testSubject as UltraTabPageControl;
if (asUltraPage != null)
{
tabSwitches.Insert(0, testSubject);
testSubject = asUltraPage.TabControl;
}
else
{
var asGroupContainer = testSubject as UltraExplorerBarContainerControl;
if (asGroupContainer != null)
{
tabSwitches.Insert(0, testSubject);
testSubject = asGroupContainer.Parent;
}
}
}
if (testSubject != null)
{
testSubject = testSubject.Parent;
}
}
#endregion
foreach (Control control in tabSwitches)
{
try
{
var page = control as UltraTabPageControl;
if (page != null)
{
page.TabControl.SelectedTab = page.Tab;
}
else
{
var asTabPage = control as TabPage;
if (asTabPage != null)
{
var tabControl = asTabPage.Parent as TabControl;
tabControl.SelectedTab = asTabPage;
}
else
{
var asExplorerContainer = control as UltraExplorerBarContainerControl;
if (asExplorerContainer != null)
{
var explorerBar = (control.Parent as UltraExplorerBar);
var explorerGroup = explorerBar.Groups[control.Name];
if (explorerBar.SelectedGroup != explorerGroup)
{
explorerBar.SelectedGroup = explorerGroup;
}
}
}
}
}
catch (Exception exp)
{
exp.LogError();
result = false;
}
}
if (shouldActivateControl)
{
subject.Select();
}
}
return result;
}
(Edit: Fixed some typos)