我有一个窗口,我有命令绑定到小键盘键,如下所示:
<!-- Set keybindings -->
<controls:MetroWindow.InputBindings>
<!-- NumPad Shortcuts for selecting reasons -->
<KeyBinding Key="NumPad0" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="0" />
<KeyBinding Key="NumPad1" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="1" />
<KeyBinding Key="NumPad2" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="2" />
<KeyBinding Key="NumPad3" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="3" />
<KeyBinding Key="NumPad4" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="4" />
<KeyBinding Key="NumPad5" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="5" />
<KeyBinding Key="NumPad6" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="6" />
<KeyBinding Key="NumPad7" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="7" />
<KeyBinding Key="NumPad8" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="8" />
<KeyBinding Key="NumPad9" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="9" />
<!-- Others -->
<KeyBinding Key="Back" Command="{Binding OnReasonGoBackClickedCommand}" />
<KeyBinding Key="Escape" Command="{Binding OnEscapeClickedCommand}" />
</controls:MetroWindow.InputBindings>
在后端,这被处理为:
ICommand _onReasonShortcutKeyPressedCommand;
public ICommand OnReasonShortcutKeyPressedCommand
{
get
{
return _onReasonShortcutKeyPressedCommand ??
(_onReasonShortcutKeyPressedCommand = new RelayCommand(OnReasonShortcutKeyPressedCommand_Execute));
}
}
private void OnReasonShortcutKeyPressedCommand_Execute(object param)
{
//Find which key was presses by command param
int keyPressed = Int32.Parse((string)param);
// Do something bla bla bla
}
现在,此窗口还包含一些必须输入数字的文本框。当然,窗口级别的键绑定导致触发命令而不是打印的实际数字。无论如何我可以覆盖它吗?
答案 0 :(得分:0)
不确定是否有更好的解决方法,但我的建议是使用attach属性来存档。 这是一个例子:
在XAML中,您应该将新行为(LimitBindings)附加到TextBox:
XAML:
<TextBox behavs:KeyBindingBehavior.LimitKeyBindings="True"></TextBox>
并创建你的行为类(+ Helper方法来获取父窗口 - 应该放在其他地方:)):
public static class KeyBindingBehavior
{
//to keep window's bindings.
private static InputBindingCollection windowBindings;
public static bool GetLimitKeyBindings(DependencyObject obj)
{
return (bool)obj.GetValue(LimitKeyBindingsProperty);
}
public static void SetLimitKeyBindings(DependencyObject obj, bool value)
{
obj.SetValue(LimitKeyBindingsProperty, value);
}
public static readonly DependencyProperty LimitKeyBindingsProperty =
DependencyProperty.RegisterAttached(
"LimitKeyBindings",
typeof(bool),
typeof(KeyBindingBehavior),
new PropertyMetadata(false, PropertyChangedCallback));
private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
TextBox textBox = dependencyObject as TextBox;
if (textBox != null)
{
textBox.GotKeyboardFocus += textBox_GotKeyboardFocus;
textBox.LostKeyboardFocus += textBox_LostKeyboardFocus;
}
}
static void textBox_LostKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
var window = GetParentWindow(sender as DependencyObject);
window.InputBindings.AddRange(windowBindings);
}
static void textBox_GotKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
var window = GetParentWindow(sender as DependencyObject);
windowBindings = new InputBindingCollection(window.InputBindings);
window.InputBindings.Clear();
}
// This helper method should be in seperate class
public static Window GetParentWindow(DependencyObject child)
{
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
if (parentObject == null)
{
return null;
}
Window parent = parentObject as Window;
if (parent != null)
{
return parent;
}
else
{
return GetParentWindow(parentObject);
}
}
}
不要忘记在XAML中添加引用以指向行为类:
xmlns:behavs="clr-namespace:WpfApplication1"