首 页 | 新 闻 | 技术中心 | 第二书店 | 《程序员》 | 《开发高手》 | 社 区 | 黄 页 | 人 才
移 动专 题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)    

积极原创作者 
btbtd (83)
coofucoo (107)
longrujun (64)
cyz1980 (101)
ssll2826 (10)
EmilMatthew (73)
goodboy1881 (15)
superlmj (12)
feng19821209 (9)
yjz0065 (115)
CSDN - 文档中心 - .NET 阅读:13210   评论: 30    参与评论
标题   Henry手记-Datagrid事件响应(二)     选择自 Latitude 的 Blog
关键字   datagrid 事件响应 .net
出处  

                                        Henry手记 Datagrid事件响应()

                                       韩睿  ( 5/6/2003)

 

hi,大家好。对于windows form中的datagrid控件的使用,我已经写了不少文章了,但也不断地收到网友的意见,希望再多写一点。应朋友的要求,我会再针对几个问题写一些文章,希望能带给您一点启发,能够熟练地使用Datagrid,更主要是希望您能举一反三,将处理问题的方法应用到对其它控件的使用中去。

本文主要解决在Datagrid中任意点击一个格子,都会出现选中一行的需求。通过本文,您也会了解焦点与控件的关系。

这个问题看上去很简单,但是,如果您平时留心的话,每次点击单元格时,我们就会点击到一个格子的内部,而不会选中一行。想要选中一行,只能点击每行的行头。

有朋友会说,就还不简单,我们可以把处理代码写在datagridmousedown事件处理程序中,用 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内嵌的控件的事件处理程序,当然需要重新定义DatagridDataGridTableStyle

(3)      Enter事件指派给每一个列风格GridColumnStyles

(4)      编写一个内嵌textboxEnter事件处理程序;

(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的事件处理程序如下,把你点击的那个textboxvisible设为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/


相关文章
对该文的评论
jilong4 ( 2004-12-27)
遇到一个问题,为何焦点在DataGrid内的Textbox时,按Enter触发不了事件,要按Shift+Enter才能触发?而按其它键则可以
dai2003 ( 2004-06-26)
psusong ,品德真差,你用你的VC,人家用人家的VB,用你的想法去强加与别人,是不是有点越轨和过分的行为,幸亏中国向你这样的人毕竟不多,要不然中国的软件也早就”关门大吉”了
xxlb ( 2004-03-15)
我很喜欢你的文章,我在用datagrid的时候遇到了一个问题,怎么样让datagrid的列宽度随着这列的内容的最大宽度而转变,也就是说,以前vb6里面的textwidth在.net里面没后替代品,应该怎么来实现!
eagle19811219 ( 2004-03-10)
呵呵
好经典的文章
谢谢你
xlt771111 ( 2003-12-18)
感谢henry!对你的修养表示敬佩。。。。