2

I'm relatively new to WPF and I am struggling to manage the focus of an element at runtime. I have a simple user control with a TextBox inside

<UserControl [...]
    IsVisibleChanged="UserControl_IsVisibleChanged">
    [...]
    <TextBox x:Name="myTextBox" [...] />
</UserControl>

That I added on my WPF window

<ctrl:MyPanel
     x:Name="myPanel"
     Visibility="{Binding MyBooleanProperty}"
     Panel.ZIndex="999" />

MyBooleanProperty is changing at runtime under some logic and the panel is showing up accordingly. I need to have keyboard focus on myTextBox everytime myPanel becomes visible so user can enter data without using mouse, tab key or anything else.

Here's the logic on the event handler of IsVisibleChanged

private void UserControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
     if (this.Visibility == Visibility.Visible)
     {
          myTextBox.Focus();
          myTextBox.SelectAll();
     }
}

This works, but if I click any button on the window before myPanel becomes visible then I cannot set focus in myTextBox. I've tried many things, for example setting

Focusable="False"

on the buttons with no luck.

Thanks in advance for your help!

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86

1 Answers1

1

After a little more searching I found a workaround based on this answer by Rachel:

Dispatcher.BeginInvoke(DispatcherPriority.Input,
                       new Action(delegate () {
                                  myTextBox.Focus();
                                  Keyboard.Focus(myTextBox);
                                  myTextBox.SelectAll();
                       }));

Delegating the focus action actually works.

  • I've been banging my head against this problem for hours. My theory is that WPF does something like this internally: 1. Receive input from user or your code that IsVisible has changed 2. Call registered handlers for IsVisibleChanged 3. Update focus according to its own logic. Any handlers in step 2 which change focus are overridden in step 3. By queueing your delegate to be executed afterwards, you are safe from whatever focus-stealing happens in step 3. – Hugh W Feb 20 '23 at 09:04