仅在获得焦点时将 Return 按键绑定到文本框

Bind Return key press to text box only while focused

我想给 TextBox 添加一个键绑定,这样当我按下 ENTER 键时,就会触发相应的命令,但我只想这样做当 TextBox 关注它时发生。

下面的代码添加了绑定,但是只要按下 Return 键,无论焦点在 window 中的哪个位置,它都会触发.是否可以将键绑定限制为仅当 TextBox 具有焦点时?

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

这是默认行为。如果我把下面两个TextBoxes放在一个StackPanel里,把键盘焦点给第二个然后按ENTER,命令是not 被解雇了。

<StackPanel>
    <TextBox Text="{Binding SearchBoxNumber, UpdateSourceTrigger=PropertyChanged}">
        <TextBox.InputBindings>
            <KeyBinding Key="Return" Command="{Binding SearchCommand}" />
        </TextBox.InputBindings>
    </TextBox>

    <TextBox />
</StackPanel>

您可以向 SearchCommand.CanExecute 添加条件,以便当焦点不在 TextBox 时 returns false。不幸的是,IsFocusedIsKeyboardFocusedIsKeyboardFocusWithin 都是只读 DP,您将无法从标记 (XAML) 绑定到它们,即使您设置了ModeOneWayToSource。为此,您可以创建自己的派生自 TextBox 的控件。

public class FocusAwareTextBox : TextBox
{
    protected override void OnIsKeyboardFocusWithinChanged(DependencyPropertyChangedEventArgs e)
    {
        if (e.OldValue != e.NewValue && e.NewValue != null)
        {
            HasFocus = (bool)e.NewValue;
        }

        base.OnIsKeyboardFocusWithinChanged(e);
    }

    public bool HasFocus
    {
        get { return (bool)GetValue(HasFocusProperty); }
        set { SetValue(HasFocusProperty, value); }
    }

    public static readonly DependencyProperty HasFocusProperty =
        DependencyProperty.Register(
            nameof(HasFocus),
            typeof(bool),
            typeof(FocusAwareTextBox),
            new PropertyMetadata(false));
}

然后,您将 HasFocus DP 绑定到 ViewModel 中的新布尔值 属性,并在 SearchCommand.CanExecute.[=24 中添加对此布尔值 属性 的检查=]

另一种解决方案是改为处理 KeyDown 事件并从那里调用命令。请注意,您必须使用 Behavior 来保持 MVVM 模式。