I’m trying to write an extension method that will allow me to set focus on a Control. I’ve written the method below which works fine, however if the control is already loaded then obviously hooking up the Loaded event isn’t going to be any use – I also need a way to check if the control has been loaded so I can simply run the Focus() code without hooking up the event.
Is there any way to simulate an IsLoaded property on a control?
public static void SetFocus(this Control control)
{
// return if the control is not visible
if (control.Visibility == Visibility.Collapsed) { return; }
control.Loaded += (sender, routedeventArgs) =>
{
// focus the Silverlight plugin first
System.Windows.Browser.HtmlPage.Plugin.Focus();
control.IsTabStop = true; // required to allow Focus
control.Focus();
if (control is TextBox)
{
((TextBox)control).SelectAll();
}
};
}
EDIT: As per ColinE’s answer below, I implemented it like this:
public static void SetFocus(this Control control)
{
// return if the control is not visible
if (control.Visibility == Visibility.Collapsed) { return; }
if (control.Descendants().Count() > 0)
{
// already loaded, just set focus and return
SetFocusDelegate(control);
return;
}
// not loaded, wait for load before setting focus
control.Loaded += (sender, routedeventArgs) =>
{
SetFocusDelegate(control);
};
}
public static void SetFocusDelegate(Control control)
{
// focus the Silverlight plugin first
System.Windows.Browser.HtmlPage.Plugin.Focus();
control.IsTabStop = true; // required to allow Focus
control.Focus();
if (control is TextBox)
{
((TextBox)control).SelectAll();
}
}
If a control has not been loaded, then the various elements within its template will not have been constructed. Using Linq-to-VisualTree you can confirm this:
The first debug output should show ‘0’, the second will be a number >0 which indicates the number of child elements of the control once the template has been applied.