tags:

views:

1557

answers:

4

It seems that when a WPF application starts, nothing has focus.

This is really weird. Every other framework I've used does just what you'd expect: puts initial focus on the first control in the tab order. But I've confirmed that it's WPF, not just my app -- if I create a new Window, and just put a TextBox in it, and run the app, the TextBox doesn't have focus until I click on it or press Tab. Yuck.

My actual app is more complicated than just a TextBox. I have several layers of UserControls within UserControls. One of those UserControls has Focusable="True" and KeyDown/KeyUp handlers, and I want it to have the focus as soon as my window opens. I'm still somewhat of a WPF novice, though, and I'm not having much luck figuring out how to do this.

If I start my app and press the Tab key, then focus goes to my focusable control, and it starts working the way I want. But I don't want my users to have to hit Tab before they can start using the window.

I've played around with FocusManager.FocusedElement, but I'm not sure which control to set it on (the top-level Window? the parent that contains the focusable control? the focusable control itself?) or what to set it to.

What do I need to do to get my deeply-nested control to have initial focus as soon as the window opens? Or better yet, to focus the first focusable control in the tab order?

+3  A: 

You can use your main window's FocusManager to set focus on the element you want at runtime.

In your window:

<Windw
  ...
  FocusManager.FocusedElement="{Binding ElementName=FocusOnMeLolKThx}"
  ...

In your user control:

<UserControl
  ...>
  <TextBox Name="FocusOnMeLolKThx">
    ...
Will
I take it you didn't try this before posting, because it doesn't work. (grin) The Binding expression doesn't find FocusOnMeLolKThx when it's inside a nested control.
Joe White
I've been working on UserControls this weekend and I've started to notice issues with binding. So, yes, you're right, I didn't try it, and I'm not surprised it isn't working. I'm guessing you have to wait until after the entire visual tree has been deserialized that this kind of trick would work. Next step--have you tried it on the textbox itself?
Will
+5  A: 

I had the bright idea to dig through Reflector to see where the Focusable property is used, and found my way to this solution. I just need to add the following code to my Window's constructor:

Loaded += (sender, e) =>
    MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));

This will automatically select the first control in the tab order, so it's a general solution that should be able to be dropped into any window and Just Work.

Joe White
Add turn that into a behavior.<Window FocusBehavior.FocusFirst="true">...</Window>
wekempf
@wekempf, I wasn't familiar with the idea of behaviors, but I looked into it and that's not a bad idea at all. If anyone else (like me) isn't already familiar with attached behaviors, here's an explanation: http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx
Joe White
+1  A: 

I found another possible solution. Mark Smith posted a FirstFocusedElement markup extension for use with FocusManager.FocusedElement.

<UserControl x:Class="FocusTest.Page2"
    xmlns:FocusTest="clr-namespace:FocusTest"
    FocusManager.FocusedElement="{FocusTest:FirstFocusedElement}">
Joe White
A: 

This works, too:

FocusManager.FocusedElement="{Binding ElementName=name of control}"

Sean