Henry手记 - Datagrid事件响应(二)
点击次数:10 次 发布日期:2008-11-26 11:14:08 作者:源代码网
|
源代码网推荐 源代码网推荐 本文主要解决在Datagrid中任意点击一个格子,都会出现选中一行的需求。通过本文,您也会了解焦点与控件的关系。 源代码网推荐 源代码网推荐 这个问题看上去很简单,但是,如果您平时留心的话,每次点击单元格时,我们就会点击到一个格子的内部,而不会选中一行。想要选中一行,只能点击每行的行头。 源代码网推荐 源代码网推荐 有朋友会说,就还不简单,我们可以把处理代码写在datagrid的mousedown事件处理程序中,用 hitTest判断选中的是哪一行哪一列的那个格子,然后就select那一行。 源代码网推荐 源代码网推荐 但是,……。当你照着做一下就会发现,不对了!每次点击了以后,还是老样子,焦点跑到textbox内部去了。这…… 源代码网推荐 源代码网推荐 难道是Datagrid偷赖没有做我们要求它做的事!哦,你冤枉它了,其实它还是执行了的!只不过执行的速度太快了,我们根本没看清人家工作的结果。是谁动了它的奶酪? 源代码网推荐 源代码网推荐 如果你看过我以前的文章,应该就不难理解:用户鼠标向Datagrid的一格点去->Datagrid先接收到焦点,执行你要求它的事件->然后焦点就会落入此格内嵌的textbox中去,使textbox聚焦。(详细分析,请看拙作《Datagrid事件响应(一) 》) 源代码网推荐 源代码网推荐 明白了吧,在datagrid刚刚执行了选中一行的操作之后,它内嵌的textbox就会引发一个聚焦事件,致使datagrid不再选中一行,而是把焦点更改到你所点击的内嵌textbox中去了。 源代码网推荐 源代码网推荐 所以,现在的解决思路就应该是:把代码写在焦点刚落入到datagrid内嵌的textbox中时的那个事件里。而对于textbox来说,焦点的落入与离开的过程都会激发什么事件,我们应该在什么事件中去写选中当前行的代码呢? 源代码网推荐 源代码网推荐 按顺序来说,焦点会引发的控件事件为: 源代码网推荐 源代码网推荐 顺序号 源代码网推荐 源代码网推荐 源代码网推荐 事件名 源代码网推荐 源代码网推荐 源代码网推荐 事件意义 源代码网推荐 源代码网推荐 1 源代码网推荐 源代码网推荐 源代码网推荐 Enter 源代码网推荐 源代码网推荐 源代码网推荐 焦点进入了控件 源代码网推荐 源代码网推荐 2 源代码网推荐 源代码网推荐 源代码网推荐 GotFocus 源代码网推荐 源代码网推荐 源代码网推荐 控件接收了焦点 源代码网推荐 源代码网推荐 3 源代码网推荐 源代码网推荐 源代码网推荐 Leave 源代码网推荐 源代码网推荐 源代码网推荐 输入焦点离开了控件 源代码网推荐 源代码网推荐 4 源代码网推荐 源代码网推荐 源代码网推荐 Validating 源代码网推荐 源代码网推荐 源代码网推荐 控件正在进行验证 源代码网推荐 源代码网推荐 5 源代码网推荐 源代码网推荐 源代码网推荐 Validated 源代码网推荐 源代码网推荐 源代码网推荐 控件完成了验证 源代码网推荐 源代码网推荐 6 源代码网推荐 源代码网推荐 源代码网推荐 LostFocus 源代码网推荐 源代码网推荐 源代码网推荐 控件失去焦点 源代码网推荐 源代码网推荐 那么,第一个会被引发的事件就是Enter了!好了,我们开工吧! 源代码网推荐 源代码网推荐 现在把要做的工作梳理一下: 源代码网推荐 源代码网推荐 (1) 找一个用于Datagrid的绑定数据源,使Datagrid有显示的数据; 源代码网推荐 源代码网推荐 (2) 要写Datagrid内嵌的控件的事件处理程序,当然需要重新定义Datagrid的DataGridTableStyle; 源代码网推荐 源代码网推荐 (3) 把Enter事件指派给每一个列风格GridColumnStyles; 源代码网推荐 源代码网推荐 (4) 编写一个内嵌textbox的Enter事件处理程序; 源代码网推荐 源代码网推荐 (5) 打完收工! 源代码网推荐 源代码网推荐 程序如下: 源代码网推荐 源代码网推荐 dim Dataset1 as New DataSet 源代码网推荐 源代码网推荐 Dim dt As DataTable’ 源代码网推荐 源代码网推荐 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 源代码网推荐 源代码网推荐 "构建一简单的dataset 源代码网推荐 源代码网推荐 dt = DataSet1.Tables.Add("MyTable") 源代码网推荐 源代码网推荐 dt.Columns.Add("Col1", GetType(String)) 源代码网推荐 源代码网推荐 dt.Columns.Add("Col2", GetType(Integer)) 源代码网推荐 源代码网推荐 Dim row, row1 As DataRow 源代码网推荐 源代码网推荐 row = dt.NewRow() 源代码网推荐 源代码网推荐 row!Col1 = "name" 源代码网推荐 源代码网推荐 row!Col2 = 123 源代码网推荐 源代码网推荐 dt.Rows.Add(row) 源代码网推荐 源代码网推荐 row1 = dt.NewRow() 源代码网推荐 源代码网推荐 row1!Col1 = "xxx" 源代码网推荐 源代码网推荐 row1!Col2 = 123 源代码网推荐 源代码网推荐 dt.Rows.Add(row1) 源代码网推荐 源代码网推荐 "构建完毕 源代码网推荐 源代码网推荐 DataGrid2.DataSource = dt 源代码网推荐 源代码网推荐 Dim ts As New DataGridTableStyle() "就是它决定了datagrid是什么样的 源代码网推荐 源代码网推荐 Dim aColumnTextColumn As DataGridTextBoxColumn "要重写的东东 源代码网推荐 源代码网推荐 DataGrid1.DataSource = dt 源代码网推荐 源代码网推荐 ts.MappingName = dt.TableName 源代码网推荐 源代码网推荐 Dim numCols As Integer 源代码网推荐 源代码网推荐 numCols = dt.Columns.Count 源代码网推荐 源代码网推荐 Dim i As Integer = 0 源代码网推荐 源代码网推荐 Do While (i < numCols) "重绘所有的列 源代码网推荐 源代码网推荐 aColumnTextColumn = New DataGridTextBoxColumn() 源代码网推荐 源代码网推荐 "夺过对textbox内落下光标的控制权 源代码网推荐 源代码网推荐 AddHandler aColumnTextColumn.TextBox.Enter, New EventHandler(AddressOf TextBoxEnterHandler) 源代码网推荐 源代码网推荐 "要更改列头名,请改下句的HeaderText值 源代码网推荐 源代码网推荐 aColumnTextColumn.HeaderText = dt.Columns(i).ColumnName 源代码网推荐 源代码网推荐 aColumnTextColumn.MappingName = dt.Columns(i).ColumnName 源代码网推荐 源代码网推荐 ts.GridColumnStyles.Add(aColumnTextColumn) "增加一种自定义的column风格 源代码网推荐 源代码网推荐 i = (i + 1) 源代码网推荐 源代码网推荐 Loop 源代码网推荐 源代码网推荐 DataGrid1.TableStyles.Clear() 源代码网推荐 源代码网推荐 DataGrid1.TableStyles.Add(ts) "增加一种自定义的表风格 源代码网推荐 源代码网推荐 End Sub 源代码网推荐 源代码网推荐 Private Sub TextBoxEnterHandler(ByVal sender As Object, ByVal e As System.EventArgs) 源代码网推荐 源代码网推荐 DataGrid1.Select(DataGrid1.CurrentRowIndex) 源代码网推荐 源代码网推荐 End Sub 源代码网推荐 源代码网推荐 运行一下,然后我们来点击看看,咦,为什么被点击的那一格会有一块空白的东东,如图1所示: 源代码网推荐 源代码网推荐 源代码网推荐 源代码网推荐 图1 空白的东东 源代码网推荐 源代码网推荐 我们还有什么没考虑到?当然有,就是我最开始时所说的,Datagrid是一个网格,在每一个单元格之间还是有它的结构存在,要不用什么去安装一个个的textbox呀(想一下往面团里放芝麻的过程,那个面团就是datagrid,芝麻就是内嵌的控件,可以是textbox,可以是checkbox,可以是combobox,可以是其它的许多控件。合在一起,就是……烧饼,哈!看来又饿了)。 源代码网推荐 源代码网推荐 在被选中的这一格里,由于textbox是聚焦了,所以Datagrid在这一格里的部分就部屏蔽了。现在想要把它们都选中,方法很简单,就是仿照Datagrid的正常操作过程来做。什么时候一行能全部被选中,当然是点击行头,从焦点的角落来说,就是这一行没有一个单元格中有焦点落下! 源代码网推荐 源代码网推荐 所以,重写一下Enter的事件处理程序如下,把你点击的那个textbox的visible设为false吧,它消失了,datagrid的整行才能被选中: 源代码网推荐 源代码网推荐 Private Sub TextBoxEnterHandler(ByVal sender As Object, ByVal e As System.EventArgs) 源代码网推荐 源代码网推荐 Dim inner As Control = sender 源代码网推荐 源代码网推荐 inner.Visible = False 源代码网推荐 源代码网推荐 DataGrid1.Select(DataGrid1.CurrentRowIndex) 源代码网推荐 源代码网推荐 End Sub 源代码网推荐 源代码网推荐 祝大家在SARS的阴影中保持健康与快乐,幸福永远与勤奋的你同在! 源代码网推荐 源代码网推荐 ---- 源代码网推荐 源代码网推荐 声明:本文版权与解释权归韩睿所有,如需转载,请保留完整的内容及此声明。 源代码网推荐 源代码网推荐 QQ: 18349592 源代码网推荐 源代码网推荐 E-Mail: henry7685@hotmail.com 源代码网推荐 源代码网推荐 请访问本人专栏:http://www.csdn.net/develop/author/netauthor/Latitude/ 做人要厚道,请注明转自酷网动力(www.ASPCOOL.COM)。 源代码网推荐 源代码网供稿. |
