У меня есть поле поиска в моем приложении WPF с кнопкой поиска, которая содержит привязку команды. Это отлично работает, но как я могу использовать ту же командную привязку для текстового поля при нажатии клавиши ввода на клавиатуре? Примеры, которые я видел, используют код Code с обработчиком событий KeyDown. Есть ли разумный способ сделать эту работу только с привязкой xaml и команд?
WPF: Выполнение привязки команды в поле поиска при нажатии кнопки ввода
Ответ 1
Вы можете использовать свойство IsDefault кнопки:
<Button Command="SearchCommand" IsDefault="{Binding ElementName=SearchTextBox,
Path=IsKeyboardFocused}">
Search!
</Button>
Ответ 2
Принятый ответ работает только если у вас уже есть кнопка, привязанная к команде.
Чтобы избежать этого ограничения, используйте TextBox.InputBindings:
<TextBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding Path=MyCommand}"></KeyBinding>
</TextBox.InputBindings>
Ответ 3
Prism Ссылка Реализация содержит реализацию именно того, что вы после.
Основные этапы:
- Создать статический класс EnterKey
- Зарегистрированное прикрепленное свойство "Команда" типа ICommand on EnterKey
- Зарегистрированное прикрепленное свойство "EnterKeyCommandBehavior" типа EnterKeyCommandBehavior on EnterKey
- Когда значение "Command" изменяется, присоедините "EnterKeyCommandBehavior" к элементу управления как новый экземпляр EnterKeyCommandBehavior и назначьте ICommand свойству Command.
- Если поведение уже установлено, используйте существующий экземпляр
- EnterKeyCommandBehavior принимает UIElement в конструкторе и присоединяется к PreviewKeyDown (или KeyDown, если вы хотите оставаться совместимым с Silverlight).
- В обработчике событий, если клавиша Enter, выполните ICommand (если CanExecute истинно).
Это позволяет вам использовать такое поведение:
<TextBox prefix:EnterKey.Command="{Binding Path=SearchCommand}" />
Ответ 4
Я пробовал решение TextBox.Inputs Грега Самсона, но получил сообщение об ошибке, что я могу привязываться только к textinputs через свойство зависимостей. В итоге я нашел следующее решение для этого.
Создайте класс CommandReference, который выглядит так:
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
}
В Xaml добавьте это в ресурсы UserControl:
<UserControl.Resources>
<Base:CommandReference x:Key="SearchCommandRef" Command="{Binding Path = SomeCommand}"/>
Фактический TextBox выглядит следующим образом:
<TextBox Text="{Binding Path=SomeText}">
<TextBox.InputBindings>
<KeyBinding Command="{StaticResource SearchCommandRef}" Key="Enter"/>
</TextBox.InputBindings>
</TextBox>
Я не помню, откуда я получил этот код, но этот сайт также объясняет это;