備忘録的なSomething

素敵なAnything

【C#,WPF,MVVM】TextBox上でEnterキーが押されたときにコマンドを実行する

例えば検索ボックスで、TextBox上でEnterキーが押されたら検索を実行したい、みたいな場合、KeyBinding を使うとキーが押されたときにコマンドを実行できます。
このとき、もちろん検索文字列も欲しいので、入力された文字列を CommandParameter で渡してあげる必要があります。
以下の例では RelativeSource で直上の TextBox (つまり自分の親)の Text プロパティを CommandParameter に渡しています。

        <TextBox Text="{Binding SearchText.Value}">
            <TextBox.InputBindings>
                <KeyBinding Key="Enter"
                            Command="{Binding SearchCommand}"
                            CommandParameter="{Binding Text, RelativeSource={RelativeSource AncestorType={x:Type TextBox}}}" />
            </TextBox.InputBindings>
        </TextBox>

サンプルコード

MVVMフレームワークとして ReactiveProperty を使用しています。

MainWindow.xaml

<Window x:Class="WpfTestApp.Windows.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" SizeToContent="WidthAndHeight" ResizeMode="NoResize">
    <StackPanel>
        <TextBox Text="{Binding SearchText.Value}">
            <TextBox.InputBindings>
                <KeyBinding Key="Enter"
                            Command="{Binding SearchCommand}"
                            CommandParameter="{Binding Text, RelativeSource={RelativeSource AncestorType={x:Type TextBox}}}" />
            </TextBox.InputBindings>
        </TextBox>
        <TextBlock Text="{Binding DisplayText.Value}" />
    </StackPanel>
</Window>

MainWindowViewModel.cs

    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public ReactivePropertySlim<string> SearchText { get; } = new ReactivePropertySlim<string>();
        public ReactivePropertySlim<string> DisplayText { get; } = new ReactivePropertySlim<string>();
        public ReactiveCommand SearchCommand { get; } = new ReactiveCommand();

        public MainWindowViewModel()
        {
            SearchCommand.Subscribe(parameter =>
            {
                var input = parameter as string;

                // ここで検索とかの処理をやる
                DisplayText.Value = input;
            });
        }
    }

実行結果:
f:id:kmua:20211124201636p:plain
↓(Enterキー押下)
f:id:kmua:20211124201655p:plain
※ 見やすさのためMargin等を別途設定しています

参考: