如何从WPF中的子控件中获取键盘?

发布于 2024-09-25 07:46:20 字数 1208 浏览 0 评论 0原文

我在窗口中有一些输入绑定:

<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);

这工作正常。但是,每当我在列表框中选择一个项目(该项目是窗口的子项)时,KeyBindings 就会停止工作。如何让父级捕获键绑定,无论哪个子级拥有焦点(如果有)。 (无论如何,事件不应该冒泡吗?)

我知道有一个 PreviewKeyDown 事件就是这样做的,但这会使我的 ICommand 毫无用处,所以我更喜欢声明式解决方案如果可能的话。

提前致谢。

I have some inputbindings in a Window:

<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>

The commands are defined in my viewmodel as 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;
}

In the ViewModel's constructor:

StepNext = new RelayCommand(DoStepNext, CanStepNext);

This works fine. However, whenever I select an item in a listbox (which is a child of the Window), the KeyBindings stop working. How can I make the parent capture the keybindings regardless of which child has focus (if any). (shouldn't the events bubble up anyway?)

I'm aware that there is a PreviewKeyDown event that does just this, but that would make my ICommands useless, so I'd prefer a declarative solution if possible.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

煮茶煮酒煮时光 2024-10-02 07:46:20

据我所知,没有声明性的方法可以使处理的事件继续冒泡。

正如您所说,最简单的方法是处理 Preview 事件。

作为替代方案,您可以重写 ListBox 类 OnKeyDown 方法,如下所示:

protected override void OnKeyDown(KeyEventArgs e)
{
    base.OnKeyDown(e);
    if (e.Key == Key.Space || e.Key == Key.Left)
        e.Handled = false;
}

As far as I know, there is no declarative way to make handled events continue bubbling up.

As you said, the simplest way is to handle Preview events.

As an alternative, you can override your ListBox class OnKeyDown method like this:

protected override void OnKeyDown(KeyEventArgs e)
{
    base.OnKeyDown(e);
    if (e.Key == Key.Space || e.Key == Key.Left)
        e.Handled = false;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文