在WPF中的鼠标事件处理程序中无法读取键的保持状态 - 在VMWare Fusion for Mac上的Windows虚拟机中行为不一致
在WPF中的鼠标事件处理程序中无法读取键的保持状态 - 在VMWare Fusion for Mac上的Windows虚拟机中行为不一致
这个问题是由于vmware fusion中的设置不一致引起的 - MacOS的辅助鼠标功能(即右键)在控制键左键点击时被触发,尽管在vmware fusion的设置中配置为将控制键发送为单独的按键。\n我将这里留下来以概述所采取的诊断步骤来隔离问题。\n这种行为可能存在于MacOS上的其他虚拟化解决方案中。\n这不是一个重复的问题 - 我已经尝试了建议的方法 - 它们不起作用。请提供真正的帮助。\n我正在尝试在WPF画布中实现多选功能,并且需要能够在点击项目时检测到任何一个控制键是否被按下。\n我已经尝试过使用文档和被接受的方法来获取键(Keyboard.IsKeyDown和Keyboard.Modifiers),尽管它们应该工作,但在这种情况下却不起作用。\n我无法在应用程序的主窗口中放置一个键处理程序,因为这个解决方案是在一个组件中实现的,因此我无法访问主窗口。\n我无法创建一个键盘OnKeyDown覆盖,因为它不注册事件。我不知道为什么,但可以说,在Stack Overflow上进行了广泛的搜索后,我已经尝试了所有方法,目前已经没有更多的想法了。\n在当前的逻辑中,点击画布中的项目将清除任何已选择的项目。如果按住控制键,则不会清除已选择的项目。\n我的应用程序的结构如下:\n主窗口 - >停靠面板 - >滚动查看器 - >主自定义组件(扩展Canvas) - >ChildCanvas对象(多个实例,也都扩展Canvas)。\n该组件不会有任何对主窗口的引用 - 这是绝对不可协商的。\n该组件不能要求传入对主窗口的引用。\n该组件不能依赖于在MainWindow中放置任何逻辑、属性、方法或其他功能代码 - 它必须是完全可重用的。\n在一个扩展Canvas上放置了多个自定义对象(ChildCanvas),该自定义对象本身也继承自Canvas。\n我在自定义项中的鼠标事件处理程序中检测鼠标点击。\n尽管从理论上讲,我可以处理键盘事件并在按下键时设置一个bool标志,当松开键时清除它,但这不是一种可靠的方式,因为它需要焦点在处理键的组件上。\n我查看的所有示例都需要特定的键按下事件处理程序,但在这种情况下,我无法应用该方法,因为即使在事件处理程序所在的组件具有焦点的情况下,它似乎也无法注册键按下事件。\n如果可能的话,我希望找到一种在鼠标点击处理程序中检查键是否按下的方法。\n编辑:我已经尝试过使用Keyboard.Modifiers的方法,但没有返回结果。\n编辑:我还尝试过Keyboard.IsKeyDown(Key.LeftCtrl),但没有返回任何值。\n编辑:我尝试通过在EventManager上注册来全局处理键事件,如所示。我发现按下和松开事件会迅速触发。第一个事件的属性e.IsRepeat为false,所有后续事件发生时都将e.IsRepeat设置为true。使用这些事件,我设置了一个bool,在第一个keyDown事件中,如果e.IsRepeat为false(第一次按键),则设置为true,并在keyUp事件中如果e.IsRepeat为false(物理释放按键时)设置为false。\n这不起作用 - 在按住键时点击画布上的项会改变bool的状态,将其设置为false。\n这种行为与Microsoft文档中描述的键盘处理方式完全不一致。\nEventManager.RegisterClassHandler(typeof(Control),Keyboard.KeyDownEvent,new KeyEventHandler(keyDown),true);\n我可以调用Keyboard.IsKeyToggled(Key.LeftCtrl),它确实显示了切换的状态,但它随着每次按键而改变,并且无法显示我在鼠标点击时键是否按下。\npublic class ExtendedCanvas:Canvas {\n public ExtendedCanvas() {\n MouseUp += thisMouseUp;\n }\n void thisMouseUp(object sender,MouseButtonEventArgs e) {\n if ((Keyboard.Modifiers & ModifierKeys.Control) > 0) {\n //这不起作用 - 没有键被注册,因为由于某种原因,Keyboard.Modifiers没有注册键是否按下。\n }\n //如果按住CONTROL键\n if (!ControlKeyHeldDown) {\n ClearSelectedItems();\n }\n IsSelected = true; \n }\n}
在MacOS上运行的VMWare Fusion中的不一致行为是由于VMWare选项引起的。尽管VMWare Fusion被配置为直接发送Control键,但Control Click仍会触发二级鼠标按钮(在这种情况下是右键点击)。
解决方法如下:
1) 关闭虚拟机。
2) 在VMWare Fusion首选项->键盘和鼠标->鼠标快捷键中,如果未选中,请启用(勾选)"Secondary Button"选项。
3) 关闭首选项窗口以保存设置。
4) 关闭VMWare Fusion。
5) 重新启动主机系统。
6) 在VMWare Fusion首选项->键盘和鼠标->鼠标快捷键中,如果选中,请禁用(取消勾选)"Secondary Button"选项。
7) 启动虚拟机,并确认Control Click不再触发二级点击。
在将VMWare Fusion从8升级到10之前,此选项已被配置为直接发送Control键。似乎尽管未选中二级功能复选框,该属性被设置为true,并且其行为与设置所建议的不一致。