2
votes

In my WPF application I have a text box control. The text box control is located in a UserControl which in turn has a View Model class. In my VM class I have a Command, which get executed either when a button is clicked in UserControl or when the Enter key is pressed. My problem is that when I press Enter, the text box loses focus and I have to click on the text box to get it focused again. What can I do to make the textbox keep focus when the key is pressed ?

I try to make a sketch on what I'm using right now:

<Window>  
    <uc:DesignPanel ... />
    <uc:CommandPrompt ... />  
</Window>

<UserControl Name=CommandPrompt ...>
    <StackPanel>
        <TextBox Name="tb_commands" />
        <Button Name="btn_process" FocusManager.FocusedElement="{Binding ElementName=tb_commands}" />
    </StackPanel>      
</UserControl>  

The DesignPanel user control in turn contains other user controls (UCOperands). The UCOperand basically looks like this:

<UserControl Name="UCOperand" Focusable="true">  
    <UserControl.InputBindings ... />  
</UserControl>

Note here that I have set Focusable="true" on the UCOperand, this is needed because otherwise the user cannot invoke the input commands defined on this contrl. If I remove this property or set it to false, then everything works just as I expect, e.g. when I press Enter while I'm editing the "tb_commands" text box or click on "btn_process" button the focus is kept on the text box. But as it is now, whenever hit Enter or click on the button, the tb_commands loses focus.

Thanks in advance.

2

2 Answers

0
votes

Add a Storyboard with a short duration to your Window and use the Completed event to set focus to the Textbox (see bottom of my sample).

<Window x:Class="TextboxFocus.Views.MainView"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:uc="clr-namespace:TextboxFocus.Views" 
  KeyDown="Window_KeyDown"
  Title="Main Window" Height="400" Width="800">

  <Window.Triggers>
      <EventTrigger RoutedEvent="FrameworkElement.Loaded">
          <BeginStoryboard>
              <Storyboard BeginTime="0:0:1" Completed="Go_Completed">
              </Storyboard>
          </BeginStoryboard>
      </EventTrigger>
  </Window.Triggers>
  <DockPanel>
      <uc:CommandPrompt x:Name="UC" >
      </uc:CommandPrompt>
  </DockPanel>
</Window>


<UserControl x:Class="TextboxFocus.Views.CommandPrompt"
  Name="UCOperand" 
  Focusable="true"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Height="300" Width="300">
  <Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <TextBox Grid.Row="0" 
             x:Name="GoTextbox"/>
    <Button Grid.Row="1"  
        Content="Go"  
        FocusManager.FocusedElement="{Binding ElementName=GoTextbox}" 
        Command="{Binding GoCommand}" />
  </Grid>
</UserControl>


public partial class MainView : Window
{
  MainViewModel _mvm = new MainViewModel();

  public MainView()
  {
     InitializeComponent();

     this.DataContext = _mvm;
  }

  private void Window_KeyDown(object sender, KeyEventArgs e)
  {
     // trap the F5/Enter key and execute the query....
     if (e.Key == Key.Enter)
     {
        _mvm.GoCommand.Execute(null);
        e.Handled = true;
     }
  }

  // set focus here
  private void Go_Completed(object sender, EventArgs e)
  {
     UC.GoTextbox.Focus();
  }
}
0
votes

I'm not sure if there's some way to get it to keep focus but you should be able to handle when this happens and then you could just set the focus back to the TextBox.

Here's a MSDN sample called How to: Detect When the Enter Key Pressed

If you change the writing of the text in that sample to be yourTextBox.Focus() I'd assume it would work.