Henry手记-Datagrid键盘事件响应(二)
2006-04-09 15:48
232 查看
这篇文章写得有点晚,继上一篇推出已经快两个月了,今天看到一名网友的留言,说他还在等着看对“Enter”事件的处理,连忙放下手中的事,补上这一篇,也希望网友们不会太失望。
对于Datagrid的键盘事件响应,我们一定要分辨清楚是Datagrid自身的,还是cell单元格的键盘事件响应,处理方法是有很大区别的。大家可以参考第一篇的方法,对cell中的键盘事件进行处理。
但有个问题上一节没有交待,就是如何对Enter键、方向键、Tab键、Pgup/PgDn这些虚键进行拦截与处理?一般网友遇到这个问题,十有八九是出于这个目的:就是希望按Enter键时使光标在一行中向右一个格一个格跳(从“name”到“123”),而不是立即跳向同一列的下一行(到“xxx”)。(如图1所示)
但是,我们在上一篇中用尽方法也截不下Enter键呀,看来这一键盘响应已经被控件封装为protected型了。控件编写人员把多个预定义的键盘绑定方案封装起来,称为快捷键。我们在Keydown/KeyPress中没办法拦截到Enter键和其它一些键盘按键正是这个原因。
快捷键与菜单快捷方式被称为命令键,应用程序会在对常规输入进行处理前的消息预处理过程中对它们进行处理。命令键也就始终比常规输入键具有优先权。
ProcessCmdKey 方法首先确定控件是否有上下文菜单,如果有,则允许 ContextMenu 处理命令键。如果命令键不是菜单快捷方式,且控件有父级,那么该键传递到父级的 ProcessCmdKey 方法。净效果是命令键在控件层次结构中向上“冒”。除了用户按下的键外,键数据还指示哪些(如果有的话)修改键与该键同时按下。修改键包括 SHIFT、CTRL 和 ALT 键(成为组合键)。
这里要注意:该方法必须返回 true,以指示它已经处理完命令键,或者 false,以指示该键不是命令键。在派生类中重写 ProcessCmdKey 方法时,控件应返回 true 以指示它已处理该键。对于未由该控件处理的键,应返回调用基类的 ProcessCmdKey 方法的结果。
如果不加返回值,会默认为false。这样你明明已经修改了处理方法,却会在执行完你的命令之后,继续执行父类中定义的该键盘按键的处理方法。
那么我们怎么处理文头的命题?解决之道就是自己写一个控件,继承自现有的Datagrid控件,再重写处理命令键响应程序ProcessCmdKey,来实现我们的需求。
步骤一:在vs.net编辑器中,“文件”->“新建”->“项目”,然后选择新建一个“Windows控件库”的项目:HenryDatagrid。这样运行的结果会生成一个DLL文件,而不是EXE执行文件;
步骤二:在HenryDatagrid.vb文件代码编辑窗口中加入有阴影的这句话:
对于Datagrid的键盘事件响应,我们一定要分辨清楚是Datagrid自身的,还是cell单元格的键盘事件响应,处理方法是有很大区别的。大家可以参考第一篇的方法,对cell中的键盘事件进行处理。
但有个问题上一节没有交待,就是如何对Enter键、方向键、Tab键、Pgup/PgDn这些虚键进行拦截与处理?一般网友遇到这个问题,十有八九是出于这个目的:就是希望按Enter键时使光标在一行中向右一个格一个格跳(从“name”到“123”),而不是立即跳向同一列的下一行(到“xxx”)。(如图1所示)
但是,我们在上一篇中用尽方法也截不下Enter键呀,看来这一键盘响应已经被控件封装为protected型了。控件编写人员把多个预定义的键盘绑定方案封装起来,称为快捷键。我们在Keydown/KeyPress中没办法拦截到Enter键和其它一些键盘按键正是这个原因。
快捷键与菜单快捷方式被称为命令键,应用程序会在对常规输入进行处理前的消息预处理过程中对它们进行处理。命令键也就始终比常规输入键具有优先权。
ProcessCmdKey 方法首先确定控件是否有上下文菜单,如果有,则允许 ContextMenu 处理命令键。如果命令键不是菜单快捷方式,且控件有父级,那么该键传递到父级的 ProcessCmdKey 方法。净效果是命令键在控件层次结构中向上“冒”。除了用户按下的键外,键数据还指示哪些(如果有的话)修改键与该键同时按下。修改键包括 SHIFT、CTRL 和 ALT 键(成为组合键)。
这里要注意:该方法必须返回 true,以指示它已经处理完命令键,或者 false,以指示该键不是命令键。在派生类中重写 ProcessCmdKey 方法时,控件应返回 true 以指示它已处理该键。对于未由该控件处理的键,应返回调用基类的 ProcessCmdKey 方法的结果。
如果不加返回值,会默认为false。这样你明明已经修改了处理方法,却会在执行完你的命令之后,继续执行父类中定义的该键盘按键的处理方法。
那么我们怎么处理文头的命题?解决之道就是自己写一个控件,继承自现有的Datagrid控件,再重写处理命令键响应程序ProcessCmdKey,来实现我们的需求。
步骤一:在vs.net编辑器中,“文件”->“新建”->“项目”,然后选择新建一个“Windows控件库”的项目:HenryDatagrid。这样运行的结果会生成一个DLL文件,而不是EXE执行文件;
步骤二:在HenryDatagrid.vb文件代码编辑窗口中加入有阴影的这句话:
Public Class HenryDatagrid Inherits System.Windows.Forms.DataGrid ‘这表示新建的控件是Datagrid的派生控件
步骤三:在“类名”窗口中选择overrides,然后在“方法名称”窗口选择“ProcessCmdKey”(如图2所示)
然后就会出现一段空的ProcessCmdKey代码段,我们可以写入自己的代码:
Protected Overrides Function ProcessCmdKey (ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean Dim WM_KEYDOWN As Integer = 256 ‘消息响应的问题可以参考其他win32编程的文章 Dim WM_SYSKEYDOWN As Integer = 260 If ((msg.Msg = WM_KEYDOWN) Or (msg.Msg = WM_SYSKEYDOWN)) Then Select Case keyData Case Keys.Down MsgBox("截到下箭头键") Return True Case Keys.Up MsgBox("截到上箭头键") Return True Case Keys.Enter SendKeys.Send("{Tab}") Return True Case Keys.Control + Keys.M MsgBox("<CTRL> + m 组合键被截获") Return True Case Keys.Alt + Keys.Z MsgBox("<ALT> + z 组合键被截获") Return True End Select End If End Function
然后运行一下,生成HenryDatagrid.dll文件
步骤四:再建立一个项目,然后在新项目的设计窗口的工具箱上单击鼠标右键,在弹出菜单中选择“添加引用”,然后在.net选项卡中占击“浏览”,选择到HenryDatagrid.dll,加入进来,然后您的工具箱上会多出一个HenryDatagrid的图标,在新项目中使用HenryDatagrid来代替datagrid控件。看一下,您所需要的“Enter跳格”事件就这样完成了。
建议:您在Keys.Enter代码中的Return True去掉,看一下会有什么情况发生。
这里说句题外话,我们在重写类方法时,必须也只能使用Overridable关键字修饰的Protected
方法。这是因为在VB中是用Overridable 关键字指定属性或方法可以在派生类中重写。没有这个东东的我们也没有资格重写了。
相关文章推荐
- Henry手记 - Datagrid键盘事件响应(二)
- Henry手记-Datagrid键盘事件响应(二)
- Henry手记 - Datagrid键盘事件响应(一)
- Henry手记 - Datagrid键盘事件响应(一)
- Henry手记 - Datagrid键盘事件响应(一)
- Henry手记-Datagrid键盘事件响应(二)
- Henry手记-Datagrid事件响应(二)
- [转贴] Henry手记 - Datagrid事件响应
- Henry手记:Datagrid事件响应
- Datagrid键盘事件响应(二)
- SDL游戏开发教程03(消息循环和键盘事件响应)
- 用代码创建DataGrid的多链接及checkbox事件响应(收藏)
- 响应键盘事件
- Qt键盘事件--组合键响应方法
- 对C#中键盘响应事件的理解。
- Henry手记:WinForm Datagrid结构剖析(一)
- 如何让div span等元素能响应键盘事件操作指南
- vc中如何响应键盘和鼠标事件
- cocos2dx 弹出键盘无法响应键盘外的触摸事件
- 创建DataGrid并响应了CheckBox事件