Geeks With Blogs
The Life and Times of a Dev Yes, we're really that weird

Wow, that was a frustrating ride.  All I wanted to do was get the initial focus of the application set to a control that was being loaded as part of the application.

At first, I tried just the "Focus" command off of the control itself.  That didn't work.  Turns out, there's two types of focus, Keyboard Focus and Logical Focus.  Cool, so then I knew I could use the method:

Keyboard.Focus(IUIElement);

Except it didn't work.  No matter where I put it, it didn't work.  I even went so far as to put the control inside of the State of the root work item and then to call the Keyboard.Focus method.  Still no luck.

So after some more trudging around on the Internet, I found an article by Adam Nelson with a hack that seems to work correctly.  Basically, he's queuing the call of the KeyboardFocus method onto the thread pool and that seems to ensure that the UI thread has completed its work.

Here's what he calls his "shameful hack":

static class FocusHelper
{
    private delegate void MethodInvoker();

    public static void Focus(UIElement element)
    {
        //Focus in a callback to run on another thread, ensuring the main UI thread is initialized by the
        //time focus is set
        ThreadPool.QueueUserWorkItem(delegate(Object foo) {
            UIElement elem = (UIElement)foo;
            elem.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                (MethodInvoker)delegate()
            {
                elem.Focus();
                Keyboard.Focus(elem);
            });                
        }, element);
    }
}

Does anybody know a better way to do this?

Posted on Friday, July 27, 2007 3:10 PM | Back to top


Comments on this post: WPF, CAB, and Keyboard.Focus

# re: WPF, CAB, and Keyboard.Focus
Requesting Gravatar...
Consider adding a handler for the PreviewGotKeyboardFocused event onthe UserControl so it could delegate focus correctly.

private void UserControl_PreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
if (e.OriginalSource == sender)
{
tb.Focus();
e.Handled = true;
}
}

In addition you'd also need to set Focusable to true on the UserControl.

Lastly you can add a Loaded event handler to the Page and set the initial focus to the desired UserControl instance.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
tb1.Focus();
}
Left by Varsha Mahadevan (MSFT) on Aug 06, 2007 6:24 PM

Your comment:
 (will show your gravatar)


Copyright © Robert May | Powered by: GeeksWithBlogs.net