頻繁綁定DataGridView的DataSource卻不正常顯示
最近在寫一個多線程程序,需要跨線程訪問DataGridView,綁定其DataSource,而且由於線程幾乎是每隔幾秒都會重新綁定一次DataGridView的DataSource的,所以,遇到各種蛋疼的問題。
首先說一個最常見最容易想到的辦法:
首先在主線程設置System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;,隨後去Designer.cs文件中將DataGridView的聲明修改成public static 然後,在自定義的線程中直接使用datagridview1.DataSource =dt;然後結果是程序莫名的卡死。
上網一查,大家都說跨線程訪問控件時這麽禁用跨線程調用檢查是不科學的,需要聲明一個委托來訪問,於是繼續折騰寫了如下代碼
[csharp] view plain copy
- public delegate void SetDGVSource(DataTable dt);
- public static void SetDGVSourceFunction(DataTable dt)
- {
- if (dataGridView1.InvokeRequired)
- {
- SetDGVSource delegateSetSource = new SetDGVSource(SetDGVSourceFunction);
- dataGridView1.Invoke(delegateSetSource, new object[] { dt });
- }
- else
- {
- dataGridView1.DataSource = dt;
- dataGridView1.Columns[dataGridView1.Columns.Count - 1].Visible = false;//設置最後一列不可見
- }
- }
這樣確實可以訪問了,當時,發現當程序運行了分吧鐘的樣子,問題又莫名其妙的來了:莫名的崩潰。
後來繼續查資料,在論壇看到有人說需要添加什麽綁定,發現不靠譜(WinForm程序不需要,那是ASP.NET的),繼續查閱,有人說需要將DataGridView的一個屬性改一下,
[csharp] view plain copy
- dataGridView1.AutoGenerateColumns = true;
然後我就老老實實的添加了,然後出現的問題更加奇葩
屏幕上的datagridview依然是一片空白,貌似根本沒有添加上,正當喪氣之時,猛然間發現鼠標經過datagridview的空白區時,鼠標由指針變成了手型,這不是說明datagridview裏面有東西麽!!!!!果然,將鼠標在datagridview裏面胡亂點擊拖動,就看到datagridview的一行行就這麽被我一拖,它就顯示出來了,我拖動一行就顯示一行。。。。
蛋疼無比啊!!!!
不過在進一步的Debug中,我發現,如果不是頻繁的刷新datagridview的DataSource的話,目測他又是正常的。。。
後來繼續慢慢摸索,發現,在不改變設置DataSource的綁定頻率的情況下,如果改用手動綁定DataSource,他又神奇般的好了。。。。
代碼如下:
[javascript] view plain copy
- datagridview1.Rows.Clear();
- foreach (DataRow dr in dt.Rows)
- {
- datagridview1.Rows.Add(dr["姓名"], dr["年齡"]);
- }
就這樣居然就可以解決我的問題了!真是喜極而泣。。。
也許是datagridview裏面的DataSource直接綁定有什麽機制導致了它不能夠頻繁的更新吧。只能采用手動方式。當然了,類似於上面的方法,還可以使用下面的更加簡潔的代碼
[csharp] view plain copy
- datagridview1.DataSource =dt.Copy();
最終我的代碼如下:
[csharp] view plain copy
- public static void SetDGVSourceFunction(DataTable dt)
- {
- if (dataGridView1.InvokeRequired)
- {
- SetDGVSource delegateSetSource = new SetDGVSource(SetDGVSourceFunction);
- dataGridView1.Invoke(delegateSetSource, new object[] { dt });
- }
- else
- {
- dataGridView1.DataSource = dt.Copy();
- //dataGridView1.Rows.Clear();
- //foreach(DataRow dr in dt.Rows)
- // dataGridView.Rows.Add(dr["姓名"],dr["年齡"]);
- dataGridView1.AutoGenerateColumns = true;
- dataGridView1.Columns[dataGridView1.Columns.Count - 1].Visible = false;//設置最後一列不可見
- }
- }
然後再在其他文件的其他的線程中只需要調用這個函數即可,便可成功的頻繁的綁定datagridview的DataSource!
頻繁綁定DataGridView的DataSource卻不正常顯示