WPF: Execute a Command Binding in a search field when pressing the enter button
Asked Answered
T

5

21

I have a search field in my WPF app with a search button that contains a command binding. This works great, but how can i use the same command binding for the text field when pressing enter on the keyboard? The examples I have seen are all using the Code behind with a KeyDown Event Handler. Is there a smart way to make this work only with xaml and command binding?

Torray answered 19/10, 2009 at 8:42 Comment(0)
L
25

You can use the IsDefault property of the button:

    <Button Command="SearchCommand" IsDefault="{Binding ElementName=SearchTextBox,
                                               Path=IsKeyboardFocused}">
         Search!
   </Button>
Leveret answered 19/10, 2009 at 9:7 Comment(4)
Thanks, easy and clean. Works great!Torray
What if you don't have a button?Bitten
This works the first time I press enter. I continue editing the search and press enter and it doesn't perform the search. I have to manually click back on the search control to get it to perform another search when I press enter.Thole
Nevermind--I'm an idiot. I forgot to add UpdateSourceTrigger=PropertyChanged on the TextBox :DThole
R
24

The accepted answer only works if you already have a button bound to the command.

To avoid this limitation, use TextBox.InputBindings:

<TextBox.InputBindings>
    <KeyBinding Key="Enter" Command="{Binding Path=MyCommand}"></KeyBinding>
</TextBox.InputBindings>
Ribosome answered 26/1, 2012 at 3:30 Comment(2)
I additionally had to change the UpdateSourceTrigger on my TextBox.Text binding to get this to work. For more details, check out Capturing the Enter key in a TextBox.Interspace
This should be the accepted answer. It works great is clean where as the accepted answer is a bit of a hack.Lundberg
R
3

The Prism Reference Implementation contains an implementation of exactly what you are after.

The basics steps are:

  • Create a static class EnterKey
  • Registered attached property "Command" of type ICommand on EnterKey
  • Registered attached property "EnterKeyCommandBehavior" of type EnterKeyCommandBehavior on EnterKey
  • When the value of "Command" changes, attach "EnterKeyCommandBehavior" to the control as a new instance of EnterKeyCommandBehavior, and assign the ICommand to the behavior's Command property.
    • If the behavior is already attached, use the existing instance
  • EnterKeyCommandBehavior accepts a UIElement in the constructor and attaches to the PreviewKeyDown (or KeyDown if you want to stay Silverlight compatible).
  • In the event handler, if the key is Enter, execute the ICommand (if CanExecute is true).

This enables you to use the behavior like so:

<TextBox prefix:EnterKey.Command="{Binding Path=SearchCommand}" />
Rawalpindi answered 19/10, 2009 at 8:59 Comment(0)
I
2
<TextBox Text="{Binding SerachString, UpdateSourceTrigger=PropertyChanged}">
    <TextBox.InputBindings>
        <KeyBinding Command="{Binding SearchCommand}" Key="Enter" />
    </TextBox.InputBindings>
</TextBox>

this should work fine.100%

Indignation answered 2/3, 2021 at 9:37 Comment(0)
R
0

I've tried the TextBox.Inputs solution of Greg Samson , but got an error saying that I could only bind to textinputs through a dependency property. In the end I've found the next solution for this.

Create a class called CommandReference which looks like this:

public class CommandReference : Freezable, ICommand
{
    public CommandReference()
    {
        //
    }

    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(CommandReference), new PropertyMetadata(new PropertyChangedCallback(OnCommandChanged)));

    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    #region ICommand Members

    public bool CanExecute(object parameter)
    {
        if (Command != null)
            return Command.CanExecute(parameter);
        return false;
    }

    public void Execute(object parameter)
    {
        Command.Execute(parameter);
    }

    public event EventHandler CanExecuteChanged;

    private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        CommandReference commandReference = d as CommandReference;
        ICommand oldCommand = e.OldValue as ICommand;
        ICommand newCommand = e.NewValue as ICommand;

        if (oldCommand != null)
        {
            oldCommand.CanExecuteChanged -= commandReference.CanExecuteChanged;
        }
        if (newCommand != null)
        {
            newCommand.CanExecuteChanged += commandReference.CanExecuteChanged;
        }
    }

    #endregion

    #region Freezable

    protected override Freezable CreateInstanceCore()
    {
        throw new NotImplementedException();
    }

    #endregion
}

In Xaml add this to the UserControl Resources:

<UserControl.Resources>
    <Base:CommandReference x:Key="SearchCommandRef" Command="{Binding Path = SomeCommand}"/>

The actual TextBox looks like this:

 <TextBox Text="{Binding Path=SomeText}">
                    <TextBox.InputBindings>
                        <KeyBinding Command="{StaticResource SearchCommandRef}" Key="Enter"/>
                    </TextBox.InputBindings>
                </TextBox>

I don't remember where I got this code from, but this site explains it as well;

http://www.netframeworkdev.com/windows-presentation-foundation-wpf/invoke-a-command-with-enter-key-after-typing-in-a-textbox-21909.shtml

Rachele answered 8/3, 2013 at 8:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.