我想看看用户是否按下了例如鼠标左键+ ctrl 键并为其调用一个事件。
我已经尝试过了,但没有成功:
[DllImport("user32.dll")]
static extern short GetAsyncKeyState(int VirtualKeyPressed);
while (true)
{
if (GetAsyncKeyState(0x01)>0)
{
DoJob();
}
else
{
}
}
此代码的问题是它第一次会捕获它,但第二次不会(这是在 while 循环中运行)
我相信您可以通过附加
Window.InputBind
和 MouseBinding
来完成您想要完成的任务,例如 Gesture="Ctrl+LeftClick"
。
如果您采用这种方法,您可以避免使用
user32.dll
并且必须处理检测隐藏代码中的输入。
这是一个将命令绑定到整个
Window
的输入的简单示例:
<Window.InputBindings>
<MouseBinding Command="{Binding CtrlLeftClickCommand}"
Gesture="Ctrl+LeftClick">
</MouseBinding>
</Window.InputBindings>
代码隐藏
public partial class GlobalHotKey : Window
{
public MouseGesture CtrlLeftClick = new MouseGesture(MouseAction.LeftClick, ModifierKeys.Control);
public ICommand CtrlLeftClickCommand { get; set; } = new CtrlLeftClickCommand();
public GlobalHotKey()
{
DataContext = this;
InitializeComponent();
}
}
ICommand
实施,以防万一您不熟悉这种方法
public class CtrlLeftClickCommand : ICommand
{
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter) => true;
public void Execute(object parameter)
{
MessageBox.Show("You did the thing!");
}
}
在 WPF 中,您可以使用路由命令定义
KeyBinding
。如果您在应用程序的视觉根上处理它,您就有一个全局输入手势。
以下示例注册应用程序范围手势 Ctrl + left_mousebutton 并启动进程(用于演示目的)。
您可以定义和处理
CommandBing
(推荐)或 InputBinding
。
通常,您会将
CommandBinding
添加到定义 UIElement.Commandings
集合中以注册与实例的绑定。Window
实例,其中每个实例定义其自己的可视化树的根。现在,我们不必为每个实例显式注册 CommandBinding
,而是在 WPF 的 Window
帮助器类的帮助下为 CommandManager
类型注册一次绑定:
MainWindow.xaml.cs
partial class MainWindow : Window
{
// Define as public so that the command can be used directly e.g., with a Button
public static RoutedCommand StartProcessCommand { get; }
public static MainWindow()
{
// Initialize a routed command with associated input gestures.
// In this case the input gesture is a MouseGesture with a pressed modifier key (Ctrl).
// Alternative track the CTRL key and create a KeyGesture instead.
// Then, when executing the command,
// we can check if 'Mouse.LeftButton == MouseButtonState.Pressed'
var startProcessHotKey = new MouseGesture(MouseAction.LeftClick, ModifierKeys.Control);
MainWindow.StartProcessCommand = new RoutedCommand(nameof(MainWindow.StartProcessCommand), typeof(MainWindow));
_ = MainWindow.StartProcessCommand.InputGestures.Add(startProcessHotKey);
}
public MainWindow()
{
InitializeComponent();
// Create a CommandBinding to register the input event handlers
var startProcessCommandBinding = new CommandBinding(
MainWindow.StartProcessCommand,
ExecutedStartProcessCommand,
CanExecuteStartProcessCommand);
// Register the command with every Window of this application.
// The Window is always the root of a visual tree.
CommandManager.RegisterClassCommandBinding(typeof(Window), startProcessCommandBinding);
}
private void CanExecuteStartProcessCommand(object sender, CanExecuteRoutedEventArgs e)
=> e.CanExecute = true;
private void ExecutedStartProcessCommand(object sender, ExecutedRoutedEventArgs e)
{
// TODO::Execute StartProcessCommand
}
}
MainWindow.xaml
Ctrl + LMouseButton 将从当前应用程序的每个
MainWindow.StartProcessCommand
实例执行 Window
。StartProcessCommand
,例如通过Button
:
<Window>
<Button Command="{x:Static MainWindow.StartProcessCommand}" />
</Window>
您可以为鼠标按下事件注册一个类处理程序,并检查相关按键是否被按下。
代码明显更短,但您失去了功能或灵活性,例如全局命令和显式命令手势的路由,允许每个元素处理它(无需显式检查确切的输入手势)。
MainWindow.xaml.cs
partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
EventManager.RegisterClassHandler(
typeof(Window),
PreviewMouseLeftButtonUpEvent,
new RoutedEventHandler(OnGlobalPreviewMouseLeftButtonUp));
}
private void OnGlobalPreviewMouseLeftButtonUp(object sender, RoutedEventArgs e)
{
if (Keyboard.IsKeyDown(Key.LeftCtrl))
{
// TODO::Execute global input gesture
}
}
}