Wpf 在我的视图模型中侦听控件键

Wpf 在我的视图模型中侦听控件键,wpf,mvvm,Wpf,Mvvm,我有一个只在按下Ctrl键时运行的工具。我正在我的视图模型中的这个函数中监听它 private ImageManipulationTool WheelTool { get { bool IsControlPressed = Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl); if (CurrentTool == loupeTool && Is

我有一个只在按下Ctrl键时运行的工具。我正在我的视图模型中的这个函数中监听它

private ImageManipulationTool WheelTool
{
    get
    {
        bool IsControlPressed = Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl);

        if (CurrentTool == loupeTool && IsControlPressed)
        {
            return loupeRadiusTool;
        }
        else if (CurrentTool == zoomTool || IsControlPressed)
        {
            return zoomTool;
        }

        // default wheel tool
        return sliceTool;
    }
}
但这并不是真正的MVVM正确。键盘基本上是视图的一个元素。现在我的代码是不可测试的,因为作为一个视图模型,我很确定即使模拟关键事件也无法工作,因为没有目标

所以我知道答案是窗口上的输入绑定。然而,我所看到的解决方案似乎并不适用于我的情况:

  • 我只使用了控制键,似乎不允许在没有“正常”键的情况下绑定到修改器键
  • 我需要知道键是否被按下,但键绑定似乎只监听键向下
  • 不太重要的是,我希望密钥绑定在我的
    UserControl
    文件中,而不是一直在
    main窗口中。但它看起来像是
    窗口。InputBindings
    就是这些需要用到的地方

  • 如何才能使所有这些都起作用?

    一种可能是在用户控件中使用事件
    PreviewKeyDown
    previewkeydup
    。从那里可以检查keystates并在viewmodel中设置属性

               private void UserControl_PreviewKeyDown(object sender, KeyEventArgs e)
                {
                        if (sender == null)
                                return;
    
                        if(sender is YourUserControl uc && uc.DataContext is YourViewModel vm)
                        {
                                if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)
                                        vm.IsCtrlKeyPressed = true;
                        }
                }
    
    执行
    PreviewKeyUp
    事件,就可以在不破坏MVVM模式的情况下使用IsCtrlKeyPressed属性了


    编辑:似乎您不需要检查
    e.KeyStates
    ,因为您始终处于
    KeyDown/Up
    事件中。但是如果你想确定的话,你可以使用
    键盘。IsKeyDown

    你能分享你的代码吗?这似乎是个好主意,但我已经将
    KeyDown=“Image\u KeyDown”
    (也可以加键,也可以预览两者)附加到
    图像
    控件上(还尝试了父控件
    用户控件
    )但是没有引发事件处理程序。我试着在没有帮助的情况下点击屏幕来移动焦点。也许你的控件没有键盘焦点。尝试附加到用户控件上的
    MouseUp
    -事件,并将键盘焦点设置为用户控件:
    Keyboard.Focus(发送方作为用户控件)