1. 程式人生 > >頻繁綁定DataGridView的DataSource卻不正常顯示

頻繁綁定DataGridView的DataSource卻不正常顯示

delegate scrip read log 綁定 sharp views ocl light

最近在寫一個多線程程序,需要跨線程訪問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. 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;
  12. dataGridView1.Columns[dataGridView1.Columns.Count - 1].Visible = false;//設置最後一列不可見
  13. }
  14. }


這樣確實可以訪問了,當時,發現當程序運行了分吧鐘的樣子,問題又莫名其妙的來了:莫名的崩潰。

後來繼續查資料,在論壇看到有人說需要添加什麽綁定,發現不靠譜(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. if (dataGridView1.InvokeRequired)
  4. {
  5. SetDGVSource delegateSetSource = new SetDGVSource(SetDGVSourceFunction);
  6. dataGridView1.Invoke(delegateSetSource, new object[] { dt });
  7. }
  8. else
  9. {
  10. dataGridView1.DataSource = dt.Copy();
  11. //dataGridView1.Rows.Clear();
  12. //foreach(DataRow dr in dt.Rows)
  13. // dataGridView.Rows.Add(dr["姓名"],dr["年齡"]);
  14. dataGridView1.AutoGenerateColumns = true;
  15. dataGridView1.Columns[dataGridView1.Columns.Count - 1].Visible = false;//設置最後一列不可見
  16. }
  17. }

然後再在其他文件的其他的線程中只需要調用這個函數即可,便可成功的頻繁的綁定datagridview的DataSource!

頻繁綁定DataGridView的DataSource卻不正常顯示