Can't set focus to a child of UserControl Can't set focus to a child of UserControl wpf wpf

Can't set focus to a child of UserControl


I recently fixed this problem for a login splash screen that is being displayed via a storyboard when the main window is first loaded.

I believe there were two keys to the fix. One was to make the containing element a focus scope. The other was to handle the Storyboard Completed event for the storyboard that was triggered by the window being loaded.

This storyboard makes the username and password canvas visible and then fades into being 100% opaque. The key is that the username control was not visible until the storyboard ran and therefore that control could not get keyboard focus until it was visible. What threw me off for awhile was that it had "focus" (i.e. focus was true, but as it turns out this was only logical focus) and I did not know that WPF had the concept of both logical and keyboard focus until reading Kent Boogaart's answer and looking at Microsoft's WPF link text

Once I did that the solution for my particular problem was straightforward:

1) Make the containing element a focus scope

<Canvas FocusManager.IsFocusScope="True" Visibility="Collapsed">    <TextBox x:Name="m_uxUsername" AcceptsTab="False" AcceptsReturn="False">    </TextBox></Canvas>

2) Attach a Completed Event Handler to the Storyboard

    <Storyboard x:Key="Splash Screen" Completed="UserNamePassword_Storyboard_Completed">...</Storyboard>

and

3) Set my username TextBox to have the keyboard focus in the storyboard completed event handler.

void UserNamePassword_Storyboard_Completed(object sender, EventArgs e){ m_uxUsername.Focus();}

Note that calling item.Focus() results in the call Keyboard.Focus(this), so you don't need to call this explicitly. See this question about the difference between Keyboard.Focus(item) and item.Focus.


Its stupid but it works:

Pop a thread that waits a while then comes back and sets the focus you want. It even works within the context of an element host.

private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e){ System.Threading.ThreadPool.QueueUserWorkItem(                   (a) =>                        {                            System.Threading.Thread.Sleep(100);                            someUiElementThatWantsFocus.Dispatcher.Invoke(                            new Action(() =>                            {                                someUiElementThatWantsFocus.Focus();                            }));                        }                   );}


Just recently I had a list-box that housed some TextBlocks. I wanted to be able to double click on the text block and have it turn into a TextBox, then focus on it and select all the text so the user could just start typing the new name (Akin to Adobe Layers)

Anyway, I was doing this with an event and it just wasn't working. The magic bullet for me here was making sure that I set the event to handled. I figure it was setting focus, but as soon as the event went down the path it was switching the logical focus.

The moral of the story is, make sure you're marking the event as handled, that might be your issue.