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?
You can use the IsDefault property of the button:
<Button Command="SearchCommand" IsDefault="{Binding ElementName=SearchTextBox,
Path=IsKeyboardFocused}">
Search!
</Button>
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>
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}" />
<TextBox Text="{Binding SerachString, UpdateSourceTrigger=PropertyChanged}">
<TextBox.InputBindings>
<KeyBinding Command="{Binding SearchCommand}" Key="Enter" />
</TextBox.InputBindings>
</TextBox>
this should work fine.100%
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;
© 2022 - 2024 — McMap. All rights reserved.