Henry手记:Datagrid事件响应

** Henry ** ** 手记 ** ** ** ** - ** ** Datagrid ** ** 事件响应 ** ** **

韩睿 ( 12/31/2002)

Happy New Year !辛苦了一年,大家可以好好放松一下,尽管这个元旦只放一天假。谢谢 CSDN 的工作人员,辛辛苦苦地忙碌了一年,服务器扩容、网站改版……希望在明年 CSDN 再接再励,工作更出色,让网友们更开心。祝福大家心想事成,万事如意!

本文主要介绍 .net Datagrid 控件的事件响应,关于事件响应机制问题请参见拙作 《 Windows 窗体引介(二) 》 。本文讨论的是 Datagrid 的鼠标响应与键盘响应问题:

** 一、 鼠标响应 **

由于 Datagrid 的集合性结构(这在拙作 Datagrid 结构剖析系列文章 中已经详细说明了),使得用户不清楚鼠标响应的响应区与处理者。请看图 1 :

图 1 Datagrid 响应区命名

** 1. 单击事件 **

如果用户要单击 datagrid 来激发某相应事件,可以使用 Datagrid.HitTest 方法来获得单击在 Datagrid 上的位置,必由系统通知您单击在何处。如下代码:

Private Sub DataGrid1_MouseDown( ByVal sender As Object , ByVal e As _

System.Windows.Forms.MouseEventArgs) Handles DataGrid1.MouseDown

Dim myGrid As DataGrid = CType (sender, DataGrid)

Dim hti As System.Windows.Forms.DataGrid.HitTestInfo

hti = myGrid.HitTest(e.X, e.Y)

Select Case hti.Type '以下展示的是该类型枚举的全部内容

Case System.Windows.Forms.DataGrid.HitTestType.None

MsgBox("你单击的是背景")

Case System.Windows.Forms.DataGrid.HitTestType.Cell

MsgBox("你单击的单元格位于行:" & hti.Row & ", 列:" & hti.Column)

Case System.Windows.Forms.DataGrid.HitTestType.ColumnHeader

MsgBox("你单击的是第" & hti.Column & "列的列头")

Case System.Windows.Forms.DataGrid.HitTestType.RowHeader

MsgBox("你单击的是第" & hti.Row & "行的行头")

Case System.Windows.Forms.DataGrid.HitTestType.ColumnResize

MsgBox("你单击的是第" & hti.Column & "列的边框")

Case System.Windows.Forms.DataGrid.HitTestType.RowResize

MsgBox("你单击的是第" & hti.Row & "行的边框")

Case System.Windows.Forms.DataGrid.HitTestType.Caption

MsgBox("你单击的是标题 ")

Case System.Windows.Forms.DataGrid.HitTestType.ParentRows

MsgBox("你单击的是父行 ")

End Select

End Sub

2. 双击事件 (感谢 acptvb 网友的帮助)

在上面的单击事件中稍加修改,就可得到双击事件,只需要在 sub 里加入如下的判断语句:

If e.Button = MouseButtons.Left And e.Clicks = 2 Then

Dim myGrid As DataGrid = CType (sender, DataGrid)

End Select

End If

您再试一下运行,却发现其它一切正常,只有单元格双击事件获得不到,这是什么原因呢?道理很简单,就是在您第一次单击 cell 时, datagrid 还可以获得消息,但是单击的结果是使焦点落入了您单击的那个 cell 中去了,您的第二次鼠标点击事件的响应者就不再是 datagrid ,而是 cell 中的 textbox 了。(如果不是很理解这个,请看一下我 专栏中的 datagrid 结构剖析文章 )。那么怎么样通知 datagrid 还有一次本属于双击 cell 事件的第二次点击呢?首先我们应该明晰何谓两次单击与双击,它们的区别就在于鼠标点击两下之间的时间间隔,间隔短的就是双击事件,达到一定长度后就被视为是两次单击(时间间隔的设定其实是可以人工完成的,在您机器的“控制面板”中有“鼠标”一项,里面就有调整这个时间间隔的工具)。这个时间设定完毕后,可以通过 SystemInformation.DoubleClickTime方法去获得。

现在我们来理一下思路:

(1) 设置一个公用变量 gridMouseDownTime,用于记录点击时的绝对时间;

(2) 在 DataGrid1_MouseDown 事件处理程序中记录下第一次点击的时间:

If hit.type= System.Windows.Forms.DataGrid.HitTestType.Cell then

gridMouseDownTime = DateTime.Now

End If

(3) 在 Datagrid 的 cell 内嵌的 textbox 中设置鼠标点击事件( mousedown ) ;

设置方法请看我 专栏中的 datagrid 结构剖析文章 ,事件处理程序的设置方法请看我专栏中的 windows 窗体引介(二) 中的事件响应部分,在此不重复解释了:

Dim ts As New DataGridTableStyle()

Dim aColumnTextColumn As DataGridTextBoxColumn

DataGrid1.DataSource = dt

Me .HenryDatagrid1.DataSource = dt

ts.MappingName = dt.TableName

Dim numCols As Integer

numCols = dt.Columns.Count

Do While (i < numCols) '重绘所有的列

aColumnTextColumn = New DataGridTextBoxColumn()

'夺过对textbox内落下光标的控制权,但你仍可以输入值

AddHandler aColumnTextColumn.TextBox.MouseDown, New MouseEventHandler _

( AddressOf TextBoxMouseDownHandler)

aColumnTextColumn.HeaderText = dt.Columns(i).ColumnName

aColumnTextColumn.MappingName = dt.Columns(i).ColumnName

ts.GridColumnStyles.Add(aColumnTextColumn) '增加一种自定义的column风格

i = (i + 1)

Loop

DataGrid1.TableStyles.Add(ts)

(4) 在上述事件的事件处理程序中比较时间间隔,从而判断是否是 datagrid 中对某一个 cell 进行了双击:

Private Sub TextBoxMouseDownHandler( ByVal sender As Object , ByVal e As MouseEventArgs)

If (DateTime.Now < gridMouseDownTime.AddMilliseconds(SystemInformation.DoubleClickTime)) Then ‘ 判断时间间隔

MsgBox("DataGrid 的 DoubleClick ")

End If

End If

End Sub

在这里需要读者注意的是,你点击的 cell 当然应该是没有被聚焦的(就是没有变蓝的),如果已经变蓝,再双击它就看不到弹出的 "DataGrid 的 DoubleClick" 对话框了,因为此时你的两次点击都是落在 textbox 里了,成为了 textbox 的双击事件,你可以在 TextBoxMouseDownHandler 中加入如下代码来进行观察:

If e.Button = MouseButtons.Left And e.Clicks = 2 Then

MessageBox.Show("在单元格的textbox中的双击 ")

Else

If (DateTime.Now < gridMouseDownTime.AddMilliseconds(SystemInformation.DoubleClickTime)) Then

MessageBox.Show("DataGrid 的 DoubleClick ")

End If

End If

您可以完善上述的代码,以实现您的鼠标事件响应的需要。

键盘事件响应看来得明年再讨论了,我得去买菜了,不然女朋友回来要发飙了。再次祝福大家新年好!

----

<P class=MsoNorma

Published At
Categories with Web编程
Tagged with
comments powered by Disqus