仅在获得焦点时将 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
。不幸的是,IsFocused
、IsKeyboardFocused
和 IsKeyboardFocusWithin
都是只读 DP,您将无法从标记 (XAML) 绑定到它们,即使您设置了Mode
到 OneWayToSource
。为此,您可以创建自己的派生自 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 模式。
我想给 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
。不幸的是,IsFocused
、IsKeyboardFocused
和 IsKeyboardFocusWithin
都是只读 DP,您将无法从标记 (XAML) 绑定到它们,即使您设置了Mode
到 OneWayToSource
。为此,您可以创建自己的派生自 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 模式。