About the First DataGridViewColumn Visible unexpected problem(关于第一列DataGridViewColumn意外可见的问题)...

问题产生时的场景:

1. 一个Windows Form项目

2. Form1, 一个TabControl拥有两个TabPage被放到Form1上

3. 在tabPage1上放置dataGridView1和2个按钮button1、button2,在tabPage2上放置dataGridView2

4. 在Form1的Load事件处理方法中创建2个DataTable,分别是dt1、dt2(每个表都有三列),并分别绑定到dataGridView1、dataGridView2上,并把dataGridView1、dataGridView2的第一列的Visible属性设置为false,来隐藏第一列

5. button1的Click事件处理方法用来更改dataGridView1的数据源表dt1, button2的Click事件处理方法用来更改dataGridView2的数据源表dt2

[在实例中只是向各自的DataTable添加一行数据]

6. 编译并启动一个程序实例,tabPage1显示了dataGridView1和两个按钮,还未切换到tabPage2,所以tabPage2和它上面的dataGridView2都还没绘制在桌面上

7. 记住,不要切换至tabPage2,保持dataGridView2一直不可见

8. 点击button1修改dt1,dataGridView1一切正常,为你添加了一行新值,并且事先隐藏掉的第一列也没有跳出来吓唬人,呵呵

9. 注意啦,现在点击button2修改dt2,即对一直还不可见的dataGridView2的数据源表进行操作,然后切换到tabPage2来显示dataGridView2,意外发生了,他就发生在你的眼前,第一列-那个事先在Form1 Load事件中已经隐藏掉的第一列竟然跳出来了,它竟然Visible了

老天可见,我在我的步骤中没有让你设置dataGridView2的第一列的Visible属性为true值啊!!!

 

问题分析:

当DataGridView控件的数据源进行操作的时候,CurrencyManager,这个Binding对象的管理者会检查它当前所在的位置。

在DataGridView中,它是怎么来确认自己的位置的呢,用reflector+Visual Studio分析+跟踪.Net源码,找到了它的确认过程:

先找出列的索引(其实问题就在这里,它以后的步骤就不分析了,对这个问题现在看来没有多大关系,所以我们只看这一段)

它会先确认CurrentCell,因为DataGridView不可见,所以没有CurrentCell,此时你也无法设置这个属性,这样的话,返回值就是一个初始的无效行列索引定位的cell,(-1,-1)。

当其判断返回值为-1时,他就会试图去直接取第一列的索引来代替无效的CurrentCell返回值,再试图获取第一列索引的时候,它会怀疑既然没有CurrentCell,那么是否意味着当前的DataGridView的Handle还未创建出来,因为dataGridView2还不可见呢,这个Handle当然还未创建出来了。

 

没办法,第一条路修改CurrentCell肯定走不通了,那是硬性规定现在是,想办法对这个IsHandleCreated属性做点手脚吧。

我也不大清楚为什么,反正在读取了一个控件的Handle属性之后,IsHandleCreated属性就变成true了,我对Windows的句柄、实例、窗体的绘制之间的关系不是很清楚,反正路是打通了,以后再慢慢学清楚这个Handle的创建吧。

再确认了当前的DataGridView的Handle已经创建了之后,它便会正确的去处可见列集合中的第一列索引了。

 

如果这个时候检测的Handle还未创建,那么它将直接返回-1,告诉剩下的程序这里连第一列都没有还搞个屁啊(其实是它只确定控件的Handle没有创建,剩下的工作还没做就返回了)。然后后面的程序便会试探的获取所有列中的第一列,包括隐藏中的列,然后将得到的第一列的Visible属性设置没true值(注意啦,原来是它,是源码把咋们的Visible属性设置为true了,让第一列蹦出来吓唬人),然后再继续做余下的工作。

 

解决方案:

好了,导致此非期望的现象的原因,大体分析出来了,解决方案也跟着出来了:

即在你对不可见的DataGridView数据源进行更改的时候,随便读一下它的Handle属性(DataGridView.Handle),使其IsHandleCreated属性早点为true,就一切OK了。

 

http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/75686026-be92-443f-a7f6-73cf26cdc37c

这个就是问题的来源,也是我写这边分析文字的初衷,花了我好长时间才追到代码出问题的大体位置,从接到帖子到跟踪代码,猜测+分析,到写完那个回复,足足花了我三个来小时的时间,蛋疼的问题啊!

看到之前还以为又是一个没有解决方案的bug,不过这个我感觉还真算一个小bug吧,最起码我感觉他的这个处理逻辑,在这方面做得不够强壮吧,我也是站着说话不腰疼,也不知道人家真要修这个bug会花多少资源,呵呵,YY一下。。。

转载于:https://www.cnblogs.com/telnet_mike/archive/2011/09/14/2176710.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值