您的位置:首页 > 编程语言 > C语言/C++

也谈VC++.NET2005中DataGrid控件的键盘事件响应

2006-05-21 16:54 363 查看
VS.NET2005中保留了数据浏览控件DataGrid,而DataGrid的键盘事件响应一般是用KeyPress、KeyDown或KeyUp事件来处理的,如果我们在编程过程中,要改变一般键值的相应事件,只需在DataGrid1的KeyPress、KeyDown或KeyUp事件中作相应的处理就可以了。如果我们要以控件库的方式来制作自己的控件,只需在自制控件的类中,重写DataGrid的PreProcessMessage方法,也可以解决问题。但以上这些方法对于DataGrid键盘事件中的快捷键与菜单快捷方式却不起作用。主要是因为快捷键与菜单快捷方式被称为命令键,应用程序会在对常规输入进行处理前的消息预处理过程中对它们进行处理。命令键也就始终比常规输入键具有优先权。命令键的键盘响应已经被控件封装为protected型了。控件编写人员把多个预定义的键盘绑定方案封装起来,称为快捷键。我们在Keydown/KeyPress中没办法拦截到Enter、SHIFT、CTRL 、ALT 键和其它一些键盘按键正是这个原因。为解决这些问题VS.NET给出了ProcessCmdKey 方法,我们可以通过重写DataGrid的ProcessCmdKey方法来改变其命令键值的相应事件 。ProcessCmdKey 方法首先确定控件是否有上下文菜单,如果有,则允许 ContextMenu 处理命令键。如果命令键不是菜单快捷方式,且控件有父级,那么该键传递到父级的 ProcessCmdKey 方法。净效果是命令键在控件层次结构中向上“冒”。除了用户按下的键外,键数据还指示哪些(如果有的话)修改键与该键同时按下。修改键包括 SHIFT、CTRL 和 ALT 键(成为组合键)。这里要注意:该方法必须返回 true,以指示它已经处理完命令键,或者 false,以指示该键不是命令键。在派生类中重写 ProcessCmdKey 方法时,控件应返回 true 以指示它已处理该键。对于未由该控件处理的键,应返回调用基类的 ProcessCmdKey 方法的结果。如果不加返回值,会默认为false。这样你明明已经修改了处理方法,却会在执行完你的命令之后,继续执行父类中定义的该键盘按键的处理方法。
我们在使用DataGrid控件时,一般都希望按Enter键时使光标在一行中从左向右一个格一个格跳(从“姓名”到“身份证号码”),而不是立即跳向同一列的下一行(到“姓名”)。(如下图所示)



要解决我们这个命题,解决之道就是自己写一个控件,继承自现有的Datagrid控件,再重写处理命令键响应程序ProcessCmdKey,来实现我们的需求。下面我就将这一过程粗略讲一下:
步骤一:在VS.NET2005编辑器的起始页中选择创建项目,然后再后续页中,选择Visual C++下的CLR,然后在Visual Studio已安装的模板中选择“Windows窗体控件库”的项目:GuoDatagrid_jl。这样生成解决方案后会生成一个DLL文件,而不是EXE执行文件。(如下图所示)



点击“确定”后进入VS.NET2005编辑器,双击GuoDatagrid_jl.h[设计]画面,进入到GuoDatagrid_jl的类编辑页面。

步骤二:在GuoDatagrid_jl..h文件代码编辑窗口中的“public ref class GuoDataGrid_jl”后面加入下面这段代码:“: public System::Windows::Forms::DataGrid”,其中“:”号后面的代码表明我们的控件是继承于DataGrid。然后再下面键入如下的代码:

public:
GuoDataGrid_jl(void)
{

}

protected:

#pragma region 重写DataGrid的ProcessCmdKey方法
virtual bool ProcessCmdKey(Message% msg, Keys keyData) override

{

if((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN))

// Listen for operating system messages.
switch (keyData)
{
case Keys::Enter:
SendKeys::Send("{Tab}");

break;
}
return DataGrid::ProcessCmdKey(msg,keyData);

}
#pragma endregion /// 清理所有正在使用的资源。

~GuoDataGrid_jl()
{
if (components)
{
delete components;
}
}

private:
static int WM_KEYDOWN = 256;
static int WM_SYSKEYDOWN = 260;
System::ComponentModel::Container^ components;

(如下图所示)



步骤三:在VS.NET2005编辑器的菜单栏中选择生成,生成一下GuoDatagrid_jl,就会得到一个.dll控件库文件,就解决了我们在Datagrid控件中按Enter键时使光标在一行中从左向右一个格一个格跳的问题了。如果要改变其他命令键的相应事件,只需在下面的选择语句中改变其对应的键值就可以了。

switch (keyData)
{
case Keys::Enter:
SendKeys::Send("{Tab}");
break;
}

使用自己自做控件时, 只需在建立项目后如下图所示



在解决方案资源管理器中点击自己项目名,再选择“引用”,然后在弹出菜单中选择“添加引用”,然后在.net选项卡中占击“浏览”,选择到GuoDatagrid_jl,加入进来,然后您的工具箱上会多出一个GuoDatagrid_jl的图标,在新项目中可以使用GuoDatagrid_jl来代替datagrid控件。

在VS.NET2005中新增加的DataGridView数据浏览控件,就不存在这样的问题,其命令键的键盘响应没有被封装为protected型了。要实现我们以上的功能,只需在窗体的DataGridView中用KeyPress、KeyDown或KeyUp事件来处理就可以了。

dx0588 二00六年5月21日于吉林长春南湖新村
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: