【问题标题】:How to grab keyboard from child controls in WPF?如何从 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 事件可以做到这一点,但这会使我的ICommands 无用,所以如果可能的话,我更喜欢声明性解决方案。

提前致谢。

【问题讨论】:

    标签: wpf xaml keyboard command


    【解决方案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 命令的示例项目中为我工作。三键响应正确。如果您愿意,我可以附加我的示例,但其中几乎没有其他内容。
    猜你喜欢
    • 2013-10-06
    • 2015-10-01
    • 2020-01-26
    • 1970-01-01
    • 2019-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多