C#winForm键盘事件

简介: 键盘事件分三种,KeyDown、KeyPress、KeyUp。执行的顺序就如我写的顺序相同。

QQ图片20220426170308.jpg

这篇日志记录下最近用到的WinForm的键盘事件。


这个其实不是很难理解,通常我之前使用的键盘事件都是绑定在按钮上的,keypress。


但是我这里将其绑定到窗体上,就可实现,按下对应的键,做对应的事情。


但是需要注意,需要将该窗体的keypreview属性设置为true!!!

 

不要小看键盘事件,他还是有很多需要注意的地方的。


1:分类


键盘事件分三种,KeyDown、KeyPress、KeyUp。执行的顺序就如我写的顺序相同。


这里需要注意一个问题:


KeyDown触发后,不一定触发KeyUp,当KeyDown 按下后,拖动鼠标,那么将不会触发KeyUp事件。

 

2:定义


KeyDown:在控件有焦点的情况下按下键时发生。

KeyPress:在控件有焦点的情况下按下键时发生。(下面会说和KeyDown 的区别)

KeyUp:在控件有焦点的情况下释放键时发生。

 

3:KeyPress 和KeyDown 、KeyPress之间的区别


KeyPress主要用来捕获数字(注意:包括Shift+数字的符号)、字母(注意:包括大小写)、小键盘等除了F1-12、SHIFT、Alt、Ctrl、Insert、Home、PgUp、Delete、End、PgDn、ScrollLock、Pause、NumLock、{菜单键}、{开始键}和方向键外的ANSI字符


**KeyDown 和KeyUp 通常可以捕获键盘除了PrScrn所有按键(这里不讨论特殊键盘的特殊键)


KeyPress 只能捕获单个字符

KeyDown 和KeyUp 可以捕获组合键。通常使用KeyUp

KeyPress 可以捕获单个字符的大小写

KeyDown和KeyUp 对于单个字符捕获的KeyValue 都是一个值,也就是不能判断单个字符的大小写。

KeyPress 不区分小键盘和主键盘的数字字符。

KeyDown 和KeyUp 区分小键盘和主键盘的数字字符。

其中PrScrn 按键KeyPress、KeyDown和KeyUp 都不能捕获。

 

KeyPress与KeyDown、KeyUp事件的区别:


1:KeyPressEventArgs类的主属性(KeyPress事件的一个参数类型)


(1).Handle属性:用来获取或设置一个值,该值指示是否处理过KeyPress事件。

(2).KeyChar属性:用来获取按下的键对应的字符,通常是该键的ASCII玛(返回的是键盘的值,如按‘K‘返回就是K)。


2:KeyEventArgs类的主属性(KeyUp和KeyDown事件的一个参数)


(1).Alt属性:用来获取一个值,该值提示是否曾按下了Alt键

(2).Control属性:用来获取一个值,该值提示是否曾按下了Crtl键

(3).Shift属性:用来获取一个值,该值提示是否曾按下了Shift键

(4).Handle属性:用来获取一个值,该值提示是否曾处理过此事件

(5).KeyCode属性:以Keys枚举值返回键盘键的键码,该属性不包含修改键信息,用于测试指定的键盘键

(6).KeyData属性:以Keys枚举值返回键盘键的键码,该属性包含修改键信息,用于判断按下键的所有信息(可返回组合键)

(7).KeyValue属性:以整数形式返回键码,而不是Keys枚举类型值。用于获得所按下键的数字表示

(8).Modifiers属性:以Keys枚举值返回所按下的修改键,仅判断修改键的信息

 

我这里要做一个上下左右箭头的功能,通过键盘和鼠标都可以对其进行控制。那么KeyPress事件便被排除在外,为了稳定,我这里选择了KeyDown事件,但是我发现我这个选择是错误的,上下左右键可以激活KeyUp事件,不能激活KeyDown事件,需要重写ProcessDialogKey方法来支持上下左右键对KeyDown事件的支持,其余两种事件也会有例子展示。


废话 不多说,上代码: (文末有实例,可下载)


首先Load事件中将KeyPreview属性设置为true,也可以在窗体的属性中设置。


/// <summary>
        /// 加载事件
        /// </summary>
        private void Form1_Load(object sender, EventArgs e)
        {
            //获取或设置一个值,该值指示在将键事件传递到具有焦点的控件前,窗体是否将接收此键事件。
            this.KeyPreview = true;
        }

 

定义四个按钮,赋予其点击事件:


/// <summary>
        /// 上箭头事件
        /// </summary>
        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("我点击了上箭头");
        }
        /// <summary>
        /// 下箭头事件
        /// </summary>
        private void button4_Click(object sender, EventArgs e)
        {
            MessageBox.Show("我点击了下箭头");
        }
        /// <summary>
        /// 右箭头事件
        /// </summary>
        private void button3_Click(object sender, EventArgs e)
        {
            MessageBox.Show("我点击了右箭头");
        }
        /// <summary>
        /// 左箭头事件
        /// </summary>
        private void button2_Click(object sender, EventArgs e)
        {
            MessageBox.Show("我点击了左箭头");
        }


效果如下图所示:


QQ图片20220426170312.jpg

 

上边只是实现了点击事件的绑定,下边我们来实现键盘事件,我们这里使用的是KeyDown事件,分别使用ASCII及键值来获取按下的键。代码如下:


/// <summary>
        /// 按键按下事件
        /// </summary>
        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            // 键码获取
            if ((Keys)e.KeyCode == Keys.Left)
            {
                button2_Click(null, null);
            }
            else if ((Keys)e.KeyCode == Keys.Right)
            {
                button3_Click(null, null);
            }
            else if ((Keys)e.KeyCode == Keys.Up)
            {
                button1_Click(sender, e);
            }
            else if ((Keys)e.KeyCode == Keys.Down)
            {
                button4_Click(sender, e);
            }
            // 键值获取
            if (e.KeyValue == 37)
            {
                button2_Click(null, null);
            }
            else if (e.KeyValue == 39)
            {
                button3_Click(null, null);
            }
            else if (e.KeyValue == 38)
            {
                button1_Click(sender, e);
            }
            else if (e.KeyValue == 40)
            {
                button4_Click(sender, e);
            }
        }

 

一定要重写这个方法,否则,上下左右按键不激活KeyDown事件。


/// <summary>
        /// 重写此方法,让其支持上下左右键
        /// </summary>
        /// <param name="keyData"></param>
        /// <returns></returns>
        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (keyData == Keys.Up || keyData == Keys.Down || keyData == Keys.Left || keyData == Keys.Right)
            {
                return false;
            }
            else
            {
                return base.ProcessDialogKey(keyData);
            }
        }

       

 

KeyPress事件:我这里绑定的是WSAD键:


/// <summary>
        /// 按键事件(按键事件)
        /// </summary>
        private void Form1_KeyPress(object sender, KeyPressEventArgs e)
        {
            // 键码获取
            if ((Keys)e.KeyChar == Keys.W)
            {
                MessageBox.Show("我点击了W键");
            }
            else if ((Keys)e.KeyChar == Keys.S)
            {
                MessageBox.Show("我点击了S键");
            }
            else if ((Keys)e.KeyChar == Keys.A)
            {
                MessageBox.Show("我点击了A键");
            }
            else if ((Keys)e.KeyChar == Keys.D)
            {
                MessageBox.Show("我点击了D键");
            }
        }

 

KeyUp事件:我这里绑定的是F1、F2、F3、F4键。


/// <summary>
        /// 按键抬起事件
        /// </summary>
        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            // 键码获取
            if ((Keys)e.KeyCode == Keys.F1)
            {
                button2_Click(null, null);
            }
            else if ((Keys)e.KeyCode == Keys.F2)
            {
                button3_Click(null, null);
            }
            else if ((Keys)e.KeyCode == Keys.F3)
            {
                button1_Click(sender, e);
            }
            else if ((Keys)e.KeyCode == Keys.F4)
            {
                button4_Click(sender, e);
            }
        }

 

以上就是基本的键盘事件的一些需要注意的地方及实例,如果在调试过程中,打断点发现对应的按键不能进入方法中,那么就是对应的方法不支持这个按键。换个方法试试就好。



目录
相关文章
|
6月前
|
C#
C# WinForm发送Email邮件
C# WinForm发送Email邮件
C# WinForm发送Email邮件
|
6月前
|
SQL 数据库连接 应用服务中间件
C#WinForm基础编程(三)
C#WinForm基础编程
153 0
|
6月前
C#WinForm基础编程(二)
C#WinForm基础编程
158 0
|
6月前
|
C# 数据安全/隐私保护
C#WinForm基础编程(一)
C#WinForm基础编程
114 0
|
11月前
|
小程序 C#
C#WinForm实现Loading等待界面
上篇博客中解决了程序加载时屏幕闪烁的问题。 但是,加载的过程变得很缓慢。 这个给用户的体验也不是很好,我这里想加一个Loading的进度条。 项目启动的时候,加载进度条,界面UI加载完毕,进度条消失。
326 0
|
关系型数据库 MySQL C#
C# winform 一个窗体需要调用自定义用户控件的控件名称
给用户控件ucQRCode增加属性: //二维码图片 private PictureBox _pictureBoxFSHLQrCode; public PictureBox PictureBoxFSHLQrCode {   get { return _pictureBoxFSHLQrCode; }   set { this.pictureBoxFSHLQrCode = value; } } 在Form1窗体直接调用即可: ucQRCode uQRCode=new ucQRCode(); ucQRCode.PictureBoxFSHLQrCode.属性= 要复制或传给用户控件上的控件的值
70 0
|
2月前
|
SQL API 定位技术
基于C#使用winform技术的游戏平台的实现【C#课程设计】
本文介绍了基于C#使用WinForms技术开发的游戏平台项目,包括项目结构、运行截图、实现功能、部分代码说明、数据库设计和完整代码资源。项目涵盖了登录注册、个人信息修改、游戏商城列表查看、游戏管理、用户信息管理、数据分析等功能。代码示例包括ListView和ImageList的使用、图片上传、图表插件使用和SQL工具类封装,以及高德地图天气API的调用。
基于C#使用winform技术的游戏平台的实现【C#课程设计】
|
25天前
|
设计模式 程序员 C#
C# 使用 WinForm MDI 模式管理多个子窗体程序的详细步骤
WinForm MDI 模式就像是有超能力一般,让多个子窗体井然有序地排列在一个主窗体之下,既美观又实用。不过,也要小心管理好子窗体们的生命周期哦,否则一不小心就会出现一些意想不到的小bug
|
1月前
|
API C# Windows
【C#】在winform中如何实现嵌入第三方软件窗体
【C#】在winform中如何实现嵌入第三方软件窗体
67 0
|
1月前
|
API C#
C#实现Winform程序右下角弹窗消息提示
C#实现Winform程序右下角弹窗消息提示
77 0