无法读取鼠标事件处理程序内 WPF 中键的保持状态 - Mac VMWare Fusion 上 Windows 来宾的行为不一致

Cannot read held state of key in WPF inside mouse event handler - Inconsistent behaviour in Windows guest on VMWare Fusion for Mac

此问题是由 vmware fusion 中的设置不一致引起的 - 尽管在vmware fusion 设置将控制作为单独的密钥发送。

我把它留在这里,因为它概述了为隔离问题而采取的诊断步骤。

MacOS 上的其他虚拟化解决方案中可能存在此行为。

这不是重复的 - 我已经尝试了建议的方法 - 它们不起作用。请提供真正的帮助。

我正在尝试在 WPF canvas 中实现多个 select 函数,并且需要能够检测在单击某个项目时何时按住任一控制键。

我已经尝试使用记录在案并被接受的方法来获取密钥(Keyboard.IsKeyDownKeyboard.Modifiers),尽管它们应该可以工作,但在这种情况下却没有。

我无法在应用程序的主 window 中放置密钥处理程序,因为此解决方案是在组件中实现的,因此,我无法访问主 window。

我无法创建键盘 OnKeyDown 覆盖,因为它没有注册事件。我不知道这是为什么,但我只想说,我已经尝试了在 Stack Overflow 上广泛搜索后可以找到的所有方法,但目前我没有想法。

在当前逻辑中,单击我的 canvas 中的项目将清除所有已 selected 的项目。如果按住控制键,我将不会清除 selected 项目。

我的应用程序结构如下:

Main Window -> Dock Panel -> ScrollViewer -> Main Custom Component (extends Canvas) -> ChildCanvas objects (multiple instances, all also extend Canvas).

该组件将不会对主组件有任何引用 window - 这是绝对没有商量余地的。

该组件不得要求将对主要 window 的引用传递给它。

组件不能依赖放置在 MainWindow 中的任何逻辑、属性、方法或其他功能代码 - 它必须完全可重用。

自身派生自 Canvas 的自定义对象 (ChildCanvas) 的多个实例被放置到也扩展了 Canvas.

的基本自定义对象 (ExtendedCanvas) 上

我在我的自定义项中的鼠标事件处理程序中检测到鼠标单击。

虽然理论上我可以处理按键事件并在按键按下时设置一个 bool 标志并在按键上升时清除它,但这不是一种可靠的做事方式,因为它需要将焦点放在在处理密钥的任何组件上。

我看过的所有示例都需要一个特定的按键事件处理程序,但我不能在这种情况下应用该方法,因为它似乎根本没有注册按键,即使事件发生的组件执行的处理程序当时具有焦点。

如果在 WPF 中可行,我想找到一种方法来检查鼠标单击处理程序中是否按下了某个键。

编辑:我尝试使用 Keyboard.Modifiers 方法,但是 return 没有结果。

编辑:我也试过 Keyboard.IsKeyDown(Key.LeftCtrl),它没有 return 任何值。

编辑:我试图通过在 EventManager 上注册来全局处理按键事件,如图所示。我发现按键弹起和按键按下事件是快速连续触发的。第一个事件将 属性 e.IsRepeat 设置为 false,所有后续事件的 e.IsRepeat 设置为 true。使用这些事件,我设置了一个布尔值,在第一个 keyDown 事件中设置为 true e.IsRepeat 为 false(第一次初始按键),并在 keyUp 中设置为 false事件如果 e.IsRepeat 为 false(keyUp 事件在物理释放键时触发)。

这不起作用 - 在按住键时单击 canvas 上的项目会更改 bool 的状态,将其设置为 false。

此行为与 Microsoft 文档中键盘处理的工作方式完全不一致。

EventManager.RegisterClassHandler(typeof(Control),
    Keyboard.KeyDownEvent,new KeyEventHandler(keyDown),true);

我可以调用 Keyboard.IsKeyToggled(Key.LeftCtrl),它确实显示了切换状态,但它会随着每次按键而改变,并且不会显示我在单击鼠标时是否按下了该键。

public class ExtendedCanvas:Canvas {
    public ExtendedCanvas() {
        MouseUp += thisMouseUp;
    }


    void thisMouseUp(object sender,MouseButtonEventArgs e) {

        if ((Keyboard.Modifiers & ModifierKeys.Control) > 0) {
            //This does not work - no key is registered, as for some reason, Keyboard.Modifiers does not register that the key is held.
        }

        //If CONTROL is held down 
        if (!ControlKeyHeldDown) {
            ClearSelectedItems();
        }

        IsSelected = true;    
    }
}

不一致的行为是 VMWare 选项的结果。

此 VM 运行 在 MacOS 上运行,尽管 VMWare Fusion 被配置为直接发送 Control 键,但 Control Click 仍会触发辅助鼠标按钮(即,在本例中为右键单击) .

解决方法是:

1) 关闭虚拟机。

2) 在 VMWare Fusion 首选项 -> 键盘和鼠标 -> 鼠标快捷方式中,启用(选中)"Secondary Button" 选项(如果未选中)。

3) 关闭首选项window 以保存设置。

4) 关闭 VMWare Fusion

5) 重启主机系统

6) 在 VMWare Fusion 首选项 -> 键盘和鼠标 -> 鼠标快捷方式中,禁用(取消选中)"Secondary Button" 选项。

7) 启动VM,确认Control Click不再触发二次点击

此选项已配置为在将 VMWare Fusion 从 8 升级到 10 之前直接发送控制。

虽然未选中辅助功能复选框,但 属性 已设置为 true,但它的行为与设置建议的方式不一致。