无法读取鼠标事件处理程序内 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.IsKeyDown
和 Keyboard.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,但它的行为与设置建议的方式不一致。
此问题是由 vmware fusion 中的设置不一致引起的 - 尽管在vmware fusion 设置将控制作为单独的密钥发送。
我把它留在这里,因为它概述了为隔离问题而采取的诊断步骤。
MacOS 上的其他虚拟化解决方案中可能存在此行为。
这不是重复的 - 我已经尝试了建议的方法 - 它们不起作用。请提供真正的帮助。
我正在尝试在 WPF canvas 中实现多个 select 函数,并且需要能够检测在单击某个项目时何时按住任一控制键。
我已经尝试使用记录在案并被接受的方法来获取密钥(Keyboard.IsKeyDown
和 Keyboard.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
.
我在我的自定义项中的鼠标事件处理程序中检测到鼠标单击。
虽然理论上我可以处理按键事件并在按键按下时设置一个 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,但它的行为与设置建议的方式不一致。