web-dev-qa-db-ja.com

TextBoxでの入力時にviewmodelsコマンドを実行する

ユーザーがTextBoxでEnterキーを押したときに、ビューモデルでコマンドを実行したい。このコマンドは、ボタンにバインドされている場合に機能します。

<Button Content="Add" Command="{Binding Path=AddCommand}" />

しかし、TextBoxから機能させることはできません。 Inputbindingを試しましたが、うまくいきませんでした。

<TextBox.InputBindings>
    <KeyBinding Command="{Binding Path=AddCommand}" Key="Enter"/>
</TextBox.InputBindings>

また、作業ボタンをデフォルトとして設定しようとしましたが、Enterキーを押しても実行されません。

ご協力いただきありがとうございます。

51
Marks

私はパーティーに遅れていることは知っていますが、これは私のために働きました。 Key="Return"の代わりにKey="Enter"を使用してみてください

完全な例はこちら

<TextBox Text="{Binding FieldThatIAmBindingToo, UpdateSourceTrigger=PropertyChanged}">
    <TextBox.InputBindings>
        <KeyBinding Command="{Binding AddCommand}" Key="Return" />
    </TextBox.InputBindings>
</TextBox>

必ずバインディングでUpdateSourceTrigger=PropertyChangedを使用してください。そうしないと、フォーカスが失われるまでプロパティが更新されず、Enterキーを押してもフォーカスが失われません。

これがお役に立てば幸いです!

139
mkamioner

おそらくコマンドをプロパティではなく、フィールドにしたのでしょう。プロパティにバインドする場合にのみ機能します。 AddCommandをプロパティに変更すると、機能します。 (XAMLは、コマンドのフィールドではなくプロパティを使用してうまく機能します->コードビハインドは不要です!)

13
Andreas Zita

これは、このために作成した添付依存関係プロパティです。コマンドが実行される前に、テキストバインディングがViewModelに更新されるようにするという利点があります(プロパティ変更更新ソーストリガーをサポートしないsilverlightに便利です)。

public static class EnterKeyHelpers
{
    public static ICommand GetEnterKeyCommand(DependencyObject target)
    {
        return (ICommand)target.GetValue(EnterKeyCommandProperty);
    }

    public static void SetEnterKeyCommand(DependencyObject target, ICommand value)
    {
        target.SetValue(EnterKeyCommandProperty, value);
    }

    public static readonly DependencyProperty EnterKeyCommandProperty =
        DependencyProperty.RegisterAttached(
            "EnterKeyCommand",
            typeof(ICommand),
            typeof(EnterKeyHelpers),
            new PropertyMetadata(null, OnEnterKeyCommandChanged));

    static void OnEnterKeyCommandChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
    {
        ICommand command = (ICommand)e.NewValue;
        FrameworkElement fe = (FrameworkElement)target;
        Control control = (Control)target;
        control.KeyDown += (s, args) =>
        {
            if (args.Key == Key.Enter)
            {
                // make sure the textbox binding updates its source first
                BindingExpression b = control.GetBindingExpression(TextBox.TextProperty);
                if (b != null)
                {
                    b.UpdateSource();
                }
                command.Execute(null);
            }
        };
    }
}

次のように使用します。

<TextBox 
    Text="{Binding Answer, Mode=TwoWay}" 
    my:EnterKeyHelpers.EnterKeyCommand="{Binding SubmitAnswerCommand}"/>
5
Mark Heath

KeyBindingのKeyプロパティの代わりにGestureを定義する必要があります。

<TextBox.InputBindings>
    <KeyBinding Gesture="Enter" Command="{Binding AddCommand}"/>
</TextBox.InputBindings>
3
Ashot Muradian

Mark Heath の答えに加えて、この方法でCommand Parameter添付プロパティを実装することで、クラスをさらに一歩進めました。

public static class EnterKeyHelpers
{
        public static ICommand GetEnterKeyCommand(DependencyObject target)
        {
            return (ICommand)target.GetValue(EnterKeyCommandProperty);
        }

        public static void SetEnterKeyCommand(DependencyObject target, ICommand value)
        {
            target.SetValue(EnterKeyCommandProperty, value);
        }

        public static readonly DependencyProperty EnterKeyCommandProperty =
            DependencyProperty.RegisterAttached(
                "EnterKeyCommand",
                typeof(ICommand),
                typeof(EnterKeyHelpers),
                new PropertyMetadata(null, OnEnterKeyCommandChanged));


        public static object GetEnterKeyCommandParam(DependencyObject target)
        {
            return (object)target.GetValue(EnterKeyCommandParamProperty);
        }

        public static void SetEnterKeyCommandParam(DependencyObject target, object value)
        {
            target.SetValue(EnterKeyCommandParamProperty, value);
        }

        public static readonly DependencyProperty EnterKeyCommandParamProperty =
            DependencyProperty.RegisterAttached(
                "EnterKeyCommandParam",
                typeof(object),
                typeof(EnterKeyHelpers),
                new PropertyMetadata(null));

        static void OnEnterKeyCommandChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
        {
            ICommand command = (ICommand)e.NewValue;
            Control control = (Control)target;
            control.KeyDown += (s, args) =>
            {
                if (args.Key == Key.Enter)
                {
                    // make sure the textbox binding updates its source first
                    BindingExpression b = control.GetBindingExpression(TextBox.TextProperty);
                    if (b != null)
                    {
                        b.UpdateSource();
                    }
                    object commandParameter = GetEnterKeyCommandParam(target);
                    command.Execute(commandParameter);
                }
            };
        }
    } 

使用法:

<TextBox Text="{Binding Answer, Mode=TwoWay}" 
    my:EnterKeyHelpers.EnterKeyCommand="{Binding SubmitAnswerCommand}"
    my:EnterKeyHelpers.EnterKeyCommandParam="your parameter"/>
0
T.Y. Kucuk