频繁绑定DataGridView的DataSource却不正常显示

Posted awangzhen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了频繁绑定DataGridView的DataSource却不正常显示相关的知识,希望对你有一定的参考价值。

最近在写一个多线程程序,需要跨线程访问DataGridView,绑定其DataSource,而且由于线程几乎是每隔几秒都会重新绑定一次DataGridView的DataSource的,所以,遇到各种蛋疼的问题。

首先说一个最常见最容易想到的办法:

首先在主线程设置System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;,随后去Designer.cs文件中将DataGridView的声明修改成public static 然后,在自定义的线程中直接使用datagridview1.DataSource =dt;然后结果是程序莫名的卡死。

上网一查,大家都说跨线程访问控件时这么禁用跨线程调用检查是不科学的,需要声明一个委托来访问,于是继续折腾写了如下代码

 

[csharp] view plain copy
 
  1. public delegate void SetDGVSource(DataTable dt);  
  2.         public static void SetDGVSourceFunction(DataTable dt)  
  3.         {  
  4.   
  5.             if (dataGridView1.InvokeRequired)  
  6.             {  
  7.                 SetDGVSource delegateSetSource = new SetDGVSource(SetDGVSourceFunction);  
  8.                 dataGridView1.Invoke(delegateSetSource, new object[] { dt });  
  9.             }  
  10.             else  
  11.             {  
  12.                 dataGridView1.DataSource = dt;  
  13.                 dataGridView1.Columns[dataGridView1.Columns.Count - 1].Visible = false;//设置最后一列不可见  
  14.   
  15.             }  
  16.         }  


这样确实可以访问了,当时,发现当程序运行了分吧钟的样子,问题又莫名其妙的来了:莫名的崩溃。

 

后来继续查资料,在论坛看到有人说需要添加什么绑定,发现不靠谱(WinForm程序不需要,那是ASP.NET的),继续查阅,有人说需要将DataGridView的一个属性改一下,

 

[csharp] view plain copy
 
  1. dataGridView1.AutoGenerateColumns = true;  


然后我就老老实实的添加了,然后出现的问题更加奇葩

 

屏幕上的datagridview依然是一片空白,貌似根本没有添加上,正当丧气之时,猛然间发现鼠标经过datagridview的空白区时,鼠标由指针变成了手型,这不是说明datagridview里面有东西么!!!!!果然,将鼠标在datagridview里面胡乱点击拖动,就看到datagridview的一行行就这么被我一拖,它就显示出来了,我拖动一行就显示一行。。。。

蛋疼无比啊!!!!

不过在进一步的Debug中,我发现,如果不是频繁的刷新datagridview的DataSource的话,目测他又是正常的。。。

后来继续慢慢摸索,发现,在不改变设置DataSource的绑定频率的情况下,如果改用手动绑定DataSource,他又神奇般的好了。。。。

代码如下:

 

[javascript] view plain copy
 
  1. datagridview1.Rows.Clear();    
  2. foreach (DataRow dr in dt.Rows)    
  3. {    
  4.     datagridview1.Rows.Add(dr["姓名"], dr["年龄"]);    
  5. }   


就这样居然就可以解决我的问题了!真是喜极而泣。。。

 

也许是datagridview里面的DataSource直接绑定有什么机制导致了它不能够频繁的更新吧。只能采用手动方式。当然了,类似于上面的方法,还可以使用下面的更加简洁的代码

 

[csharp] view plain copy
 
  1. datagridview1.DataSource =dt.Copy();  


最终我的代码如下:

 

 

[csharp] view plain copy
 
  1. public static void SetDGVSourceFunction(DataTable dt)  
  2.         {  
  3.   
  4.             if (dataGridView1.InvokeRequired)  
  5.             {  
  6.                 SetDGVSource delegateSetSource = new SetDGVSource(SetDGVSourceFunction);  
  7.                 dataGridView1.Invoke(delegateSetSource, new object[] { dt });  
  8.             }  
  9.             else  
  10.             {  
  11.                 dataGridView1.DataSource = dt.Copy();  
  12.                 //dataGridView1.Rows.Clear();  
  13.                 //foreach(DataRow dr in dt.Rows)  
  14.                 //  dataGridView.Rows.Add(dr["姓名"],dr["年龄"]);  
  15.                 dataGridView1.AutoGenerateColumns = true;  
  16.                 dataGridView1.Columns[dataGridView1.Columns.Count - 1].Visible = false;//设置最后一列不可见  
  17.   
  18.             }  
  19.         }  

 

然后再在其他文件的其他的线程中只需要调用这个函数即可,便可成功的频繁的绑定datagridview的DataSource!





以上是关于频繁绑定DataGridView的DataSource却不正常显示的主要内容,如果未能解决你的问题,请参考以下文章

非常频繁地更新datagridview

C#的dataGridView控件里面已经有数据了,怎么让它自动统计总行数?[自动统计:没有点击等任何事件时]

winform datagridview 绑定 list .c#

怎么让datagridview不自动修改绑定的datatable

C#中datagridview如何绑定ArrayList集合?

winformdatagridview绑定后一直刷新