如何从 WPF 中的子控件中获取键盘?
Posted
技术标签:
【中文标题】如何从 WPF 中的子控件中获取键盘?【英文标题】:How to grab keyboard from child controls in WPF? 【发布时间】:2011-04-19 02:32:08 【问题描述】:我在一个窗口中有一些输入绑定:
<Window.InputBindings>
<KeyBinding Key="Space" Command="Binding Path=StepNext" />
<KeyBinding Key="R" Command="Binding Path=ResetSong" />
<KeyBinding Key="Left" Command="Binding Path=StepPrevious" />
</Window.InputBindings>
这些命令在我的视图模型中定义为 RelayCommands:
public class RelayCommand : ICommand
private Action<object> _exec;
private Func<object, bool> _canExec;
public RelayCommand(Action<object> exec, Func<object, bool> canExec)
_exec = exec;
_canExec = canExec;
public void Execute(object parameter)
_exec(parameter);
public bool CanExecute(object parameter)
return _canExec(parameter);
public event EventHandler CanExecuteChanged;
在 ViewModel 的构造函数中:
StepNext = new RelayCommand(DoStepNext, CanStepNext);
这很好用。但是,每当我在列表框中选择一个项目(它是 Window 的子项)时,KeyBindings 就会停止工作。无论哪个孩子有焦点(如果有),我如何让父母捕获键绑定。 (事件不应该冒泡吗?)
我知道有一个 PreviewKeyDown 事件可以做到这一点,但这会使我的ICommand
s 无用,所以如果可能的话,我更喜欢声明性解决方案。
提前致谢。
【问题讨论】:
【参考方案1】:据我所知,没有任何声明方式可以让处理的事件继续冒泡。
如您所说,最简单的方法是处理Preview
事件。
作为替代方案,您可以像这样覆盖 ListBox
类 OnKeyDown 方法:
protected override void OnKeyDown(KeyEventArgs e)
base.OnKeyDown(e);
if (e.Key == Key.Space || e.Key == Key.Left)
e.Handled = false;
【讨论】:
感谢您的回答,我添加了更多详细信息。我怀疑我的 ICommand 实现存在一些问题,但我不知道是什么问题。 我添加了这个事件处理程序,真正有趣的是它不会为三个绑定键(空格、左键和 R)触发。我很困惑。 它在我使用绑定到现有 ApplicationCommands.open 命令的示例项目中为我工作。三键响应正确。如果您愿意,我可以附加我的示例,但其中几乎没有其他内容。以上是关于如何从 WPF 中的子控件中获取键盘?的主要内容,如果未能解决你的问题,请参考以下文章