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?