c#中给winform定义快捷键的几种方式

news2024/9/20 18:47:13

快捷键的使用在日常的开发中频率比较高,这里总结了最常见的各种快捷键的设置方式,需要的时候大家直接照抄就可以了,不用再去查询如何实现了。

文章目录

  • 一、按钮快捷键
  • 二、菜单快捷键
  • 三、窗体快捷键
  • 四、全局快捷键
    • 1、重写ProcessCmdKey
    • 2、使用KeyPreview属性捕捉快捷键
      • a.创建一个快捷键管理器类:
      • b、在窗体中使用快捷键管理器:
    • 4、用API实现
      • a、添加必要的Windows API声明:
      • b、在窗体中使用快捷键管理器:

文章原出处: https://haigear.blog.csdn.net/article/details/142202370

一、按钮快捷键

1、直接通过按钮Text定义
这个方法直接从VB沿用至今,在按钮的Text属性中使用“&+字母“即可设置,设置完成后,button的文字中就会出现一个有下划线的字母,这个就是ALT+字母的组合快键键了
在这里插入图片描述

2、通过AccessKey属性设置

对于某些控件(如按钮),虽然不能直接设置快捷键,但可以通过AccessKey属性为控件设置访问键,当控件具有焦点时,按下Alt键加上访问键字符即可触发。

// 为按钮设置访问键 'S'
button.AccessKey = 'S';

当然,这个方法不仅适合给button控件,其他的控件也是可以的。

二、菜单快捷键

使用Keys枚举和ModifierKeys枚举定义快捷键组合:
你可以通过设置控件的ShortcutKeys属性来定义快捷键。这通常用于MenuItem控件,但也可以用于其他控件。例如,为菜单项设置快捷键

  ToolStripMenuItem1.ShortcutKeys= Keys.Delete;

如果要设置组合快捷键,则可以这么来设置:

// 设置菜单项的快捷键为 Ctrl + S
menuItem.ShortcutKeys = Keys.Control | Keys.S;
menuItem.ShortcutKeysEnabled = true;

文章原出处:https://haigear.blog.csdn.net/article/details/142202370

三、窗体快捷键

窗体快捷键是在当前窗体激活的情况下有效,不可以跨窗体使用,只能在本窗体使用。使用方法很简单,即利用keydown事件的参数e对按键进行判断:

private void Form1_KeyDown(object sender, KeyEventArgs e)
{       //判断ctrl+S是否被按下
    if ((e.KeyCode == Keys.S) && e.Control)    
			MessageBox.show("CTRL+S"); 
}

这个方式充其量算作是“伪全局快捷键”,下面我们来看看真正的全局快捷键。

四、全局快捷键

1、重写ProcessCmdKey

如果你想捕捉窗体中的快捷键,可以在窗体类中重写ProcessCmdKey方法。这允许你定义全局快捷键,即使焦点不在特定控件上也能响应。

 protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == (Keys.Alt | Keys.V)) // ALT + V
            {
                // 执行保存操作
                MessageBox.Show("alt+V");
                return true; // 表示快捷键已被处理
            }
            return base.ProcessCmdKey(ref msg, keyData); // 其他快捷键传递给基类处理
        }

2、使用KeyPreview属性捕捉快捷键

将窗体的KeyPreview属性设置为true,这样窗体就可以在控件之前接收到键盘事件。然后,你可以通过KeyDown或KeyUp事件来处理快捷键。

public Form1()
{
    InitializeComponent();
    this.KeyPreview = true;
}

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Control && e.KeyCode == Keys.S)
    {
        // 执行保存操作
        yourFunction();
        e.Handled = true; // 表示快捷键已被处理
    }
}

3、使用WPF的快捷键定义法
在 WinForms 中,InputBindings 并不是直接支持的,这是 WPF (Windows Presentation Foundation) 中的一个特性。在 WinForms 中,我们通常使用其他方法来实现快捷键的功能,如之前提到的 ProcessCmdKey 方法、KeyPreview 属性以及菜单项的 ShortcutKeys 属性。

如果你希望在 WinForms 中实现类似 WPF 的 InputBindings 功能,你需要手动实现一些逻辑。以下是一个简单的示例,说明如何模拟 InputBindings 的行为
文章原出处:https://haigear.blog.csdn.net/article/details/142202370

a.创建一个快捷键管理器类:

创建一个类来存储快捷键和对应的命令或事件处理器。

using System;
using System.Collections.Generic;
using System.Windows.Forms;

public class ShortcutManager
{
    private Dictionary<Keys, Action> _shortcuts = new Dictionary<Keys, Action>();

    public ShortcutManager(Form form)
    {
        form.KeyPreview = true;
        form.KeyDown += Form_KeyDown;
    }

    private void Form_KeyDown(object sender, KeyEventArgs e)
    {
        if (_shortcuts.ContainsKey(e.KeyCode))
        {
            _shortcuts[e.KeyCode]();
            e.Handled = true;
        }
    }

    public void AddBinding(Keys key, Action action)
    {
        _shortcuts[key] = action;
    }
}

b、在窗体中使用快捷键管理器:

在窗体的构造函数中初始化快捷键管理器,并添加快捷键。

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        var shortcutManager = new ShortcutManager(this);
        
        // 添加快捷键 Ctrl+S 来触发保存操作
        shortcutManager.AddBinding(Keys.Control | Keys.S, SaveFile);
    }

    private void SaveFile()
    {
        // 实现保存文件的逻辑
    }
}

说明:
这里,ShortcutManager 类负责监听窗体的按键事件,并根据按键执行相应的动作。你可以通过调用 AddBinding 方法来添加快捷键和对应的处理函数。

一定要注意,这种方法需要你手动管理快捷键的添加和事件处理,而 WPF 中的 InputBindings 是通过 XAML 和绑定机制来实现的,WinForms 并没有直接提供这样的支持。上述方法是模拟 WPF 功能的一种方式,但需要更多的代码来实现类似的功能。
文章原出处:https://haigear.blog.csdn.net/article/details/142202370

4、用API实现

这个是为老的c++老手准备的,也许在VC中习惯了这种方式,这里也给出实现的典型代码。
在C# WinForms中使用Windows API来实现快捷键,可以通过调用RegisterHotKey和UnregisterHotKey函数来注册和注销全局快捷键。这种方法允许你捕捉到即使应用程序不在前台运行时的快捷键操作。以下是如何实现的步骤:

a、添加必要的Windows API声明:

首先,需要在你的WinForms项目中添加对Windows API的引用。这可以通过在代码文件顶部添加DllImport属性来实现。

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public class HotkeyManager
{
    // 定义Windows API函数
    [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);

    // 定义快捷键修饰符
    public const uint MOD_ALT = 0x0001;
    public const uint MOD_CONTROL = 0x0002;
    public const uint MOD_NOREPEAT = 0x4000;
    public const uint MOD_SHIFT = 0x0004;
    public const uint MOD_WIN = 0x0008;

    // 定义一个ID,用于标识快捷键
    private const int HOTKEY_ID = 9000;

    private IntPtr hWnd;

    public HotkeyManager(IntPtr hWnd)
    {
        this.hWnd = hWnd;
    }

    // 注册快捷键
    public bool RegisterHotKey(Keys key, uint modifiers)
    {
        return RegisterHotKey(this.hWnd, HOTKEY_ID, modifiers, (uint)key);
    }

    // 注销快捷键
    public void UnregisterHotKey()
    {
        UnregisterHotKey(this.hWnd, HOTKEY_ID);
    }
}

b、在窗体中使用快捷键管理器:

在你的窗体类中,创建HotkeyManager的实例,并在窗体加载时注册快捷键,在窗体关闭时注销快捷键。

public partial class MainForm : Form
{
    private HotkeyManager hotkeyManager;

    public MainForm()
    {
        InitializeComponent();
        hotkeyManager = new HotkeyManager(Handle);
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        // 注册快捷键 Ctrl + Alt + S
        hotkeyManager.RegisterHotKey(Keys.S, HotkeyManager.MOD_ALT | HotkeyManager.MOD_CONTROL);
    }

    protected override void OnFormClosing(FormClosingEventArgs e)
    {
        base.OnFormClosing(e);
        // 注销快捷键
        hotkeyManager.UnregisterHotKey();
    }

    // 快捷键响应事件
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (keyData == (Keys.Control | Keys.Alt | Keys.S))
        {
            // 执行快捷键对应的操作
            MessageBox.Show("快捷键 Ctrl + Alt + S 被触发");
            return true;
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }
}

在这个示例中,当用户按下Ctrl + Alt + S时,会触发ProcessCmdKey方法,并显示一个消息框。请确保在窗体加载时注册快捷键,并在窗体关闭时注销快捷键,以避免潜在的资源泄漏。

使用Windows API来实现全局快捷键是一种强大的方式,但需要确保正确处理资源和线程问题,特别是在涉及多线程应用程序时。这种方法允许应用程序即使在后台运行时也能响应快捷键。
文章原出处:https://haigear.blog.csdn.net/article/details/142202370
暂时能够想到的快捷键设置方式只有这些,后面如果发现什么其他的方法会随时补充的。感兴趣的童鞋可以关注博客的更新。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2142325.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++内存管理详解:各类变量的存储区域

在C中&#xff0c;变量的存储位置取决于它们的类型和生命周期。那么不同的各个变量究竟存储在哪个区域呢&#xff1f; 1.不同类型的变量 我们首先从变量类型的不同来说明&#xff1a; 1. 全局变量和静态变量 - 存储区&#xff1a;全局/静态区&#xff08;静态区&#xff0…

深度学习----------------------文本预处理

目录 文本预处理读取数据集词源化词表该部分总代码该部分总代码 整合所有功能该部分总代码 文本预处理 文本预处理&#xff1a;把文本当作一个时序序列 将解析文本的常见预处理步骤。 这些步骤通常包括&#xff1a; ①将文本作为字符串加载到内存中。 ②将字符串拆分为词元&…

Redis的存储原理和数据模型

一、Redis是单线程还是多线程呢&#xff1f; 我们通过跑redis的代码&#xff0c;查看运行的程序可以得知&#xff0c;Redis本身其实是个多线程&#xff0c;其中包括redis-server&#xff0c;bio_close_file&#xff0c;bio_aof_fsync&#xff0c;bio_lazy_free&#xff0c;io_t…

Python如何导入自定义包?

在 Python 中&#xff0c;导入包是日常开发的基础操作之一。Python 通过其模块化设计&#xff0c;使得代码可以组织成模块和包&#xff0c;提升了代码的复用性和可维护性。而当开始构建复杂的Python项目时&#xff0c;通常会发现将代码组织在各种模块和包中是非常有帮助的。自定…

【C++】list常见用法

&#x1f525;个人主页&#x1f525;&#xff1a;孤寂大仙V &#x1f308;收录专栏&#x1f308;&#xff1a;C从小白到高手 &#x1f339;往期回顾&#x1f339;&#xff1a;[C]vector常见用法 &#x1f516; 流水不争&#xff0c;争的是滔滔不息。 文章目录 一、list的介绍li…

JVM 调优篇6 可视化性能监控工具-JVisual VM

一 Visual VM 1.1 概述 Visual VM是一个功能强大的多合一故障诊断和性能监控的可视化工具。 它集成了多个JDK命令行工具&#xff0c;使用Visual VM可用于显示虚拟机进程及进程的配置和环境信息(jps,jinfo)&#xff0c;监视应用程序的CPU、GC、堆、方法区及线程的信息(jstat…

Celery的使用

Celery 一、Celery概述1. 特点:2. celery组成3. 安装与使用4. 邮箱配置二、Celery的使用实操——发送邮件1. 安装2. 配置一、Celery概述 1. 特点: 2. celery组成 配置任务队列Broker,采用redis保存要执行的任务队列 Client:任务的发出者 Worker:任务的处理者 3. 安装与使用…

从0-1 用AI做一个赚钱的小红书账号(不是广告不是广告)

大家好&#xff0c;我是胡广&#xff01;是不是被标题吸引过来的呢&#xff1f;是不是觉得自己天赋异禀&#xff0c;肯定是那万中无一的赚钱天才。哈哈哈&#xff0c;我告诉你&#xff0c;你我皆是牛马&#xff0c;不要老想着突然就成功了&#xff0c;一夜暴富了&#xff0c;瞬…

信奥初赛解析:1.2-计算机系统的基本结构

目录 知识要点 一、概述 二、计算机硬件系统 &#xff08;一&#xff09;处理器 &#xff08;二&#xff09;存储器 (1)内存储器 (2)外存储器 ①固态硬盘存储器 ②机械硬盘存储器 ③闪存 (三)输入设备 (四)输出设备 (五)总线结构 (六)主要的性能指标 1.字长 2.运…

计算机毕业设计 网上书店系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

JVM OutOfMemoryError 与 StackOverflowError 异常

目录 前言 堆溢出 虚拟机栈和本地方法栈溢出 方法区溢出 前言 JVM规范中规定, 除了程序计数器之外, 其他的运行时数据区域, 例如堆栈, 方法区, 都会出现OutOfMemoryError异常. 那么到底是怎么样的代码, 才会引起堆溢出, 栈溢出, 或者是方法区的溢出呢? 如果遇到了又该如何…

书生大模型全链路开源体系,学习

优点 书生浦语开源大模型&#xff0c;是一个开源的大模型&#xff0c;大家可以一起学习 还有配套的教学视频&#xff0c;很快就能上手&#xff0c;而且还奖励算力&#xff0c;可以直接训练&#xff0c;讨论学习&#xff0c;非常nice。 教学视频 书生浦语大模型全链路开源开…

FastAPI与环境变量:实现无缝切换与高效运维

在现代软件开发中&#xff0c;尤其是构建RESTful API时&#xff0c;环境变量的管理显得尤为重要。它们不仅允许我们在不同环境中&#xff08;如开发、测试、生产&#xff09;灵活地调整应用的行为&#xff0c;还极大地增强了应用的安全性和可维护性。FastAPI作为一个新兴的、高…

ROS组合导航笔记1:融合传感器数据

使用机器人定位包&#xff08;robot_localization package&#xff09;来合并来自不同传感器的数据&#xff0c;以改进机器人定位时的姿态估计。 基本概念 在现实生活中操作机器人时&#xff0c;有时我们需要处理不够准确的传感器数据。如果我们想要实现机器人的高精度定位&am…

苍穹外卖 修改nginx的端口后websocket连接失败解决

苍穹外卖 修改nginx的端口后websocket连接失败解决 问题&#xff1a; 后端配置好websocket后前端仍显示如图所示的错误 解决&#xff1a; 先用websocket在线工具测试后端是否能正常连接&#xff08;这个基本上不会出现问题&#xff09;用f12观察前端发送的请求 正常来说这个请…

chatgpt个人版ssrf漏洞

文章目录 免责申明搜索语法漏洞描述漏洞复现修复建议 免责申明 本文章仅供学习与交流&#xff0c;请勿用于非法用途&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任 搜索语法 fofa title"ChatGPT个人专用版"漏洞描述 该系统是一个开源的…

【两方演化博弈代码复现】:双方演化博弈的原理、概率博弈仿真、相位图、单个参数灵敏度演化

目录-基于MatLab2016b实现 一、演化博弈的原理1. 基本概念2. 参与者的策略3.演化过程 二、MATLAB 代码解读&#xff08;博弈参与主体&#xff08;双方&#xff09;策略选择的动态演化讨程&#xff09;三、MATLAB 代码解读&#xff08;博弈主体随着时间策略选择的动态演化讨程&a…

若依nday复现

前言 声明&#xff1a;此文章仅做学习&#xff0c;未经授权严禁转载。请勿利用文章内的相关技术从事非法测试&#xff0c;如因此产生的一切不良后果与文章作者无关 本文章只做简单汇总&#xff0c;在此感谢其他师傅的文章和分享 前置准备 环境搭建 下载&#xff1a;https:/…

访谈心脑血管名医黄力医生:医术精湛,心系患者

黄力医生&#xff0c;一位在心脑血管领域深耕多年的杰出医者&#xff0c;其医学之路同样始于对国内顶尖医学院校的刻苦钻研。在那里&#xff0c;她不仅打下了坚实的医学理论基础&#xff0c;更培养了对医学事业的无限热爱与崇高追求。毕业后&#xff0c;黄力医生毅然选择了心脑…

django-prometheus使用及源码分析

简介 在django服务运行过程中&#xff0c;希望可以对其获取promethues指标进行监控&#xff0c;这样可以实时知道其运行状态&#xff0c;当它运行异常时可以及时进行告警&#xff0c;并且帮助我们可以对其针对性进行优化。比如请求量过大是否要进行限流或者扩容&#xff0c;再…