首 页 | 新 闻 | 技术中心 | 第二书店 | 《程序员》 | 《开发高手》 | 社 区 | 黄 页 | 人 才
移 动专 题SUNIBM微 软微 创精 华Donews人 邮
我的技术中心 
我的分类 我的文档
全部文章 发表文章
专栏管理 使用说明



 RSS 订阅 
最新文档列表
Windows/.NET
.NET  (rss)    
Visual C++  (rss)    
Delphi  (rss)    
Visual Basic  (rss)    
ASP  (rss)    
JavaScript  (rss)    
Java/Linux
Java  (rss)    
Perl  (rss)    
综合
其他开发语言  (rss)    
文件格式  (rss)    
企业开发
游戏开发  (rss)    
网站制作技术  (rss)    
数据库
数据库开发  (rss)    
软件工程
其他  (rss)    

积极原创作者 
iiprogram (69)
qdzx2008 (50)
goodboy1881 (14)
wangchinaking (58)
fancyhf (1)
harrymeng (41)
yjz0065 (113)
coofucoo (105)
Drate (69)
lphpc (30)
CSDN - 文档中心 - .NET 阅读:12757   评论: 7    参与评论
标题   Henry手记-Datagrid键盘事件响应(二)     选择自 Latitude 的 Blog
关键字   Datagrid, VB.NET,键盘事件
出处  

             Henry手记 Datagrid键盘事件响应(二)

               韩睿  ( 03/11/2003)

这篇文章写得有点晚,继上一篇推出已经快两个月了,今天看到一名网友的留言,说他还在等着看对“Enter”事件的处理,连忙放下手中的事,补上这一篇,也希望网友们不会太失望。

 

对于Datagrid的键盘事件响应,我们一定要分辨清楚是Datagrid自身的,还是cell单元格的键盘事件响应,处理方法是有很大区别的。大家可以参考第一篇的方法,对cell中的键盘事件进行处理。

但有个问题上一节没有交待,就是如何对Enter键、方向键、Tab键、Pgup/PgDn这些虚键进行拦截与处理?一般网友遇到这个问题,十有八九是出于这个目的:就是希望按Enter键时使光标在一行中向右一个格一个格跳(从“name”到“123”),而不是立即跳向同一列的下一行(到“xxx”)。(如图1所示)

         

 

              图1 跳格演示

但是,我们在上一篇中用尽方法也截不下Enter键呀,看来这一键盘响应已经被控件封装为protected型了。控件编写人员把多个预定义的键盘绑定方案封装起来,称为快捷键。我们在Keydown/KeyPress中没办法拦截到Enter键和其它一些键盘按键正是这个原因,下面罗列的就是隐藏起来的快捷键:

 

操作

快捷键

完成单元格输入并向下移动到下一个单元格。

如果焦点在子表链接上,则导航至该表。

ENTER 键

如果处于单元格编辑模式,则取消单元格编辑。

如果处于字幕选择模式,则取消在行上的编辑。

ESC 键

当编辑单元格时,删除插入点前的字符。

BACKSPACE 键

当编辑单元格时,删除插入点后的字符。

DELETE 键

移动到当前行的第一个单元格。

HOME 键

移动到当前行的最后一个单元格。

END 键

突出显示当前单元格中的字符并将插入点置于该行的末尾。与双击单元格的行为相同。

F2 键

如果焦点在单元格上,则移动到该行中的下一个单元格。

如果焦点在某行中最后一个单元格上,则移动到该行的第一个子表链接并将其展开。

如果焦点在子链接上,则移动到下一个子链接。

如果焦点在最后一个子链接上,则移动到下一行的第一个单元格。

TAB 键

如果焦点在单元格上,则移动到该行中的上一个单元格。

如果焦点在某行中第一个单元格上,则移动到上一行中最后一个展开的子表链接,或移动到上一行中最后一个单元格。

如果焦点在子链接上,则移动到上一个子链接。

如果焦点在第一个子链接上,则移动到上一行的最后一个单元格。

SHIFT+TAB 键

Tab 键顺序移动到下一个控件。

CTRL+TAB 键

Tab 键顺序移动到上一个控件。

CTRL+SHIFT+TAB 键

如果在子表中,则向上移动到父表。与单击“后退”按钮的行为相同。

ALT+左箭头键

展开子表链接。ALT+下箭头键展开所有链接,而不仅仅是选定的链接。

ALT+下箭头键

CTRL+加号键

折叠子表链接。ALT+上箭头键折叠所有链接,而不仅仅是选定的链接。

ALT+上箭头键

CTRL+减号键

按箭头的方向移动到最远的一个非空单元格。

CTRL+箭头键

按箭头的方向将所选内容扩展一行(不包括子表链接)。

SHIFT+上/下箭头键

按箭头的方向将所选内容扩展到最远的一个非空行(不包括子表链接)。

CTRL+SHIFT+上/下箭头键

移动到左上角的单元格。

CTRL+HOME 键

移动到右下角的单元格。

CTRL+END 键

将所选内容扩展到顶端行。

CTRL+SHIFT+HOME 键

将所选内容扩展到底端行。

CTRL+SHIFT+END 键

选择当前行(不包括子表链接)。

SHIFT+SPACEBAR 键

选择整个网格(不包括子表链接)。

CTRL+A 键

当在子表中时,显示父行。

CTRL+PAGE DOWN 键

当在子表中时,隐藏父行。

CTRL+PAGE UP 键

将所选内容向下扩展一个屏幕(不包括子表链接)。

SHIFT+PAGE DOWN 键

将所选内容向上扩展一个屏幕(不包括子表链接)。

SHIFT+PAGE UP 键

为当前行调用 DataGrid.EndEdit 方法。

CTRL+ENTER 键

当处于编辑模式时,将 dbnull 值输入单元格。

CTRL+0 键

 

快捷键与菜单快捷方式被称为命令键,应用程序会在对常规输入进行处理前的消息预处理过程中对它们进行处理。命令键也就始终比常规输入键具有优先权。

ProcessCmdKey 方法首先确定控件是否有上下文菜单,如果有,则允许 ContextMenu 处理命令键。如果命令键不是菜单快捷方式,且控件有父级,那么该键传递到父级的 ProcessCmdKey 方法。净效果是命令键在控件层次结构中向上。除了用户按下的键外,键数据还指示哪些(如果有的话)修改键与该键同时按下。修改键包括 SHIFTCTRL 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所示)

 

 

        图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 关键字指定属性或方法可以在派生类中重写。没有这个东东的我们也没有资格重写了。

-------------------------

声明:本文版权与解释权归韩睿所有,如需转载,请保留完整的内容及此声明。

QQ: 18349592

E-Mail: henry7685@hotmail.com

请访问本人专栏:http://www.csdn.net/develop/author/netauthor/Latitude/


相关文章
对该文的评论
CSDN 网友 ( 2005-08-23)
麻烦~~
follyfour ( 2004-04-22)
谢谢!支持
cll007 ( 2004-03-22)
好东东!
做个记号先
bugsdownup ( 2004-01-09)
这还没有彻底解决问题。
  理想的状态是,DataGridTextBoxColumn.TextBox可以接受到enter键,并能根据具体的业务逻辑确定下一个焦点。
  这看来是一个很小的要求,但非得编写DataGridColumnStyle的一个继承类,来仿照DataGridTextBoxColumn,但使其中的TextBox对象能接受到enter键,但不把他当成命令键,而交给具体调用程序去截获和再定义呢?
  困惑中,渴盼指点,谢谢!
liuguangwei ( 2003-10-14)
认识深刻!