Capturing the Enter key in a TextBox
Asked Answered
T

5

85

In my WPF view, I am trying to tie an event to the Enter key as follows:

<TextBox Width="240" VerticalAlignment="Center" Margin="2" Text="{Binding SearchCriteria, Mode=OneWayToSource}">
  <TextBox.InputBindings>
      <KeyBinding Key="Enter" Command="{Binding EnterKeyCommand}"/>
      <KeyBinding Key="Tab" Command="{Binding TabKeyCommand}"/>
  </TextBox.InputBindings>
</TextBox>

This code works and my EnterKeyCommand fires when the users presses the Enter key. However, the problem is that when the event fires, WPF hasn't yet bound the text in the textbox to 'SearchCriteria'. So when my event fires, the contents of 'SearchCriteria' is blank. Is there a simple change I can make in this code so that I can get the contents of the textbox when my EnterKey command fires?

Trigraph answered 5/4, 2011 at 18:15 Comment(0)
F
75

You need to change the UpdateSourceTrigger on your TextBox.Text binding to PropertyChanged. See here.

Fenner answered 5/4, 2011 at 18:19 Comment(3)
Hi micahtan How can I capture Enter key in PreviewTextInput?Heffner
Hi @0MV1, the method outlined uses WPF binding. If you'd like to use PreviewTextInput, you'll have to use event handling instead.Fenner
So, basically, he should change Text="{Binding SearchCriteria, Mode=OneWayToSource}" to Text="{Binding SearchCriteria, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}" and it will work fine.Pericarp
W
25

You can do this by passing the TextBox's InputBindings property as a CommandParameter to the Command :

<TextBox x:Name="MyTextBox">
    <TextBox.InputBindings>
        <KeyBinding Key="Return" 
                    Command="{Binding MyCommand}"
                    CommandParameter="{Binding ElementName=MyTextBox, Path=Text}"/>
    </TextBox.InputBindings>
</TextBox>
Wildeyed answered 16/5, 2016 at 23:7 Comment(2)
This was spot on! This plus the info here, helped me through my confusion! #19848360Multiped
I remain confused. I put this in my text box, but nothing happens.Memberg
B
13

I know this is 6 years old but none of the answers produce the correct answer in its entirety using XAML and no code-behind.I still had some work to do. For reference the approach is the following. First the XAML

 <TextBox Text="{Binding SearchText, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
        <TextBox.InputBindings>
            <KeyBinding Key="Enter" Command="{Binding SearchEnterHit}"/>
            <KeyBinding Key="Return" Command="{Binding SearchEnterHit}"/>
        </TextBox.InputBindings>
    </TextBox>

Basically the approach is that every key is tossed to the bound SearchText on every keystroke. Thus the string will be entirely present within SearchText once the return/enter is pressed. Thus in the SearchEnterHit command the entire string within the TextBox is available via the SearchText property.

As mentioned above the UpdateSourceTrigger=PropertyChanged is what flushes every keystroke to the SearchText property. The KeyBindings capture the enter key.

This is really the simplest means of doing this with no code-behind and all XAML. Sure you are flushing keys to the SearchText property often but that generally is not a problem.

Bossuet answered 30/8, 2017 at 13:0 Comment(0)
P
10

You can also do this in the code behind.

How to: Detect When the Enter Key Pressed

In the check for enter/return, just invoke your event handler code.

Peper answered 15/3, 2013 at 22:33 Comment(1)
Code-behind should be generally avoided unless asbsolutely necessary. An input binding is much more appropriate and declarative.Innoxious
S
0

It is also can be done like async event. Here is the example.

tbUsername.KeyDown += async (s, e) => await OnKeyDownHandler(s, e);  

private async Task OnKeyDownHandler(object sender, KeyEventArgs e)
{
   if (e.Key == Key.Return)
   {
      if (!string.IsNullOrEmpty(tbUsername.Text) && !string.IsNullOrEmpty(tbPassword.Password))
      {
          Overlay.Visibility = Visibility.Visible;
          await Login();
      }
  }
}
Scot answered 28/11, 2017 at 4:31 Comment(1)
Not completely true. The KeyDown event doesn't support async, so it will already continue executing before the async method is ready.Pillion

© 2022 - 2024 — McMap. All rights reserved.