WPF 快捷键监听的多种实现方法

374 阅读3分钟

前言

在用户界面设计中,快捷键(Hotkeys)是提高用户体验和操作效率的重要工具。

对于WPF 进行开发的应用程序来说,实现快捷键监听不仅可以提升应用程序的功能性,还能显著改善用户的交互体验。

本文将详细介绍在 WPF 中实现快捷键监听的几种常见方法,并探讨适用场景。

正文

调用Win32 API(优先级最高,全局监听, 支持最小化失焦等情况)

那么,假如我要在一个 WPF 程序监听 CTRL+5 按键,首先在主窗口程序添加以下代码:

/// <summary>
/// CTRL+5事件Id
/// </summary>
private const int Ctrl5KeyEventId = 9000;


[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);

[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);


protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);

    var handle = new WindowInteropHelper(this).Handle;
    var source = HwndSource.FromHwnd(handle);
    source?.AddHook(HwndHook);
    //真正注册快捷键监听处理: 同时注册数字键和小键盘的CTRL+5
    RegisterHotKey(handle, Ctrl5KeyEventId, (uint)ModifierKeys.Control, (uint)KeyInterop.VirtualKeyFromKey(Key.D5));
    RegisterHotKey(handle, Ctrl5KeyEventId, (uint)ModifierKeys.Control, (uint)KeyInterop.VirtualKeyFromKey(Key.NumPad5));
}


private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    const int wmHotkey = 0x0312;

    switch (msg)
    {
        case wmHotkey:
            switch (wParam.ToInt32())
            {
                case Ctrl5KeyEventId:
                    Debug.WriteLine("Win32监听CTRL+5成功");
                    break;
            }
            break;
    }

    return IntPtr.Zero;
}


protected override void OnClosing(CancelEventArgs e)
{
    base.OnClosing(e);

    var handle = new WindowInteropHelper(this).Handle;
    //关闭窗口后取消注册
    UnregisterHotKey(handle, Ctrl5KeyEventId);
}

监听 WPF 的KeyDown事件(不够清真,可选择,最小化失焦等情况监听失效)

public MainWindow()
{
    InitializeComponent();
    KeyDown += MainWindow_KeyDown;
}
private void MainWindow_KeyDown(object sender, KeyEventArgs e)
{
    if (Keyboard.Modifiers == ModifierKeys.Control && (e.Key == Key.D5 || e.Key == Key.NumPad5))
    {
        Debug.WriteLine("WPF的KeyDown事件监听CTRL+5成功"); ;
        e.Handled = true;
    }
}

XAML 绑定命令方式(WPF当然优先选中命令绑定啦,清真,最小化失焦等情况监听失效)

以下为Window主窗体的XAML代码

<Window.CommandBindings>
    <CommandBinding Command="{x:Static local:Commands.Ctrl5Command}" Executed="Ctrl5Command_OnExecuted"/>
</Window.CommandBindings>
<Window.InputBindings>
    <KeyBinding Modifiers="Control" Key="D5"  Command="{x:Static  local:Commands.Ctrl5Command}" />
    <KeyBinding Modifiers="Control" Key="NumPad5"  Command="{x:Static  local:Commands.Ctrl5Command}" />
</Window.InputBindings>

在Window主窗体后台代码创建命令对应的Executed方法

private void Ctrl5Command_OnExecuted(object sender, ExecutedRoutedEventArgs e)
{
    Debug.WriteLine("WPF的XAML绑定命令监听CTRL+5成功");
}

新增命令相关的静态类:

public static class Commands
{
    public static ICommand Ctrl5Command { get; } = new RoutedCommand();
}

细节

三个监听方案的优先级

其中Win32 > XAML绑定命令 = KeyDown事件,假如同时监听的话,其中会只处理高优先级的,以上面的例子,假如

我同时监听三个,只会处理win32的

Win32监听CTRL+5成功
全局监听问题

其中win32支持全局监听键盘,也就是窗口在失焦情况下,例如最小化,也能监听得到,其中XAML绑定命令KeyDown事件不支持失焦情况,最小化等情况也就监听不到了,因此,要按业务选择方案

总结

无论是简单的快捷键设置还是复杂的全局热键管理,掌握多种实现方法可以帮助开发者更好地应对各种应用场景。希望本文的内容能够帮助您在 WPF 项目中顺利实现快捷键监听功能,进一步提升应用程序的质量和用户体验。

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

作者:RyzenAdorer

出处:cnblogs.com/ryzen/p/17235188.html

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!