tags:

views:

52

answers:

2

Hi,

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.

A: 

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.

ho1
The problem is that when the Enter key is pressed a command is invoked which in turn adds a new UserControl to my DesignPanel. The KeyDown event is not handled in the code behind, and although I tried to do it that way, it just doesn't work because I suppose the UCOperand user control gets the focus after I could call tb_commands.Focus (), so this call is useless in my case.
Zoliq
A: 

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();
  }
}
Zamboni
Thanks Zamboni for your answer, but unfortunately it doesn't really work in my scenario. Please take a look on my original post above, I made some edits on it to clarify a bit better the problem.
Zoliq
Thanks for editing your post. I changed my answer, hope this helps.
Zamboni
I tried your approach but it doesn't seem to help me out. The main problem as I think is when I add the user controls to the DesignPanel. So, when the user click on the "btn_process" button then as a result a new control is added to the DesignPanel which probably takes the focus from my text box and places on the newly created user control, UCOperand which has the Focusable="true" property set. As I said, if I remove this property setter, then it's okay but that's not option for me.
Zoliq