C# dataGridView無法隨著dataSource动态更新的解決方法

之前沒怎麼用windowForm的dataGridView控件綁定數據,所以不很多東西都不態熟,這不,剛做一個項目的時候,如下圖:

 

 圖一

當單擊“搜尋”時,如果系統中有相應的記錄,自動在下面的dataGridView中以追加的形式綁定搜出來的不同記錄。

 

剛開始的思路如下:

1、為dataGridView綁定一個靜態的List<T>類的集合,如下: 

private static List<PartSpec> listPec = new List<PartSpec>();

2、當點擊“搜尋”時,查詢數據庫,把查找到出來的記錄與dataGridView中的項進行遍歷比較,然後把不同的項目(去重的方法可見另一篇日志,稍後給出)追加至這個List<T>類的集合中。

3、這樣,dataGridView理論上是能夠實現上面的功能了。

 

圖二

 

 圖三

 

但實際上,答案是不能夠(如圖二和圖三可看出問題),於是我果斷的設斷點來追蹤了一下代碼,發現,List<T>類的數據集合已經發生了變化了,但是為什麼dataGridView卻沒有同步更新呢。找到了疑問,那麼“百度一下,你就知道了”:我真的百度了,但百了很久才找到問題所在(源網址:http://hi.baidu.com/zhangge9477/blog/item/40336802196b3e094afb51ea.html)。於是,我把這個List<T>類聲明為BindingList<T>類之後(需要引入命名空間 using System.ComponentModel;),問題果然解決了,嘿嘿,如下:

代碼把

private static List<PartSpec> listPec = new List<PartSpec>();

改為: 

private static BindingList<PartSpec> listPec = new BindingList<PartSpec>();

然後,還要把新寫一個GetProductPartBindList方法返回BindingList<PartSpec>類型的結果。

最後效果圖如下:

 

 圖四
 
這裡,我又補充一個問題:當我添加完記錄後,點擊“添加料號”按鈕就可以把勾上的記錄都保存到數據庫裡面,而這些小勾都是在每次按搜尋的時候,自動遍歷並勾選上的,代碼片斷如下:
1 dataGridView1.DataSource=dt; 
2 foreach (DataGridViewRow row in dataGridView1.Rows)
3 {
4      row.Cells[0].Value = 1;
5 }
這樣做會有一個問題,當我需要添加的記錄比較多的時候,而在添加的過程中不小心加錯了一條記錄後,按理說,我只要把前面的小勾去掉即可,然後繼續把其它記錄添加到這個dataGridview中去,但是,這個該死的遍歷會把前面去掉勾的選項會重新勾上的,所以這個東西不符合這裡的需求。我這裡說一個小思路出來:每當有新的記錄被添加進去這個dataGridview(就是BindingList<T>集合)時,只把最後的那筆記錄勾上即可,其它的不變。
那點擊“搜尋”按鈕時怎麼判斷這次單擊事件要不要勾中最後一項呢?可以比較一下dataGridview(也就是BindingList<T>)的前後Count屬性值,下面是源代碼片斷,由於有些內容比較敏感,我也不貼上來了,能看懂就看,不懂也沒事,記住一下思路即可。
 1         /// <summary>
 2         /// 掃描槍掃描編號後檢驗數據庫
 3         /// add by seasons.zhang 2012/05/25
 4         /// </summary>
 5         /// <param name="sender"></param>
 6         /// <param name="e"></param>
 7         private void txtSearch_KeyDown(object sender, KeyEventArgs e)
 8         {
 9             if (e.KeyCode == Keys.Enter)//這裡是按鍵碼為“回車”的意思
10             {
11                 BindingList<PartSpec> list = new BindingList<PartSpec>();
12                 string key = txtSearch.Text.Trim();
13                 list = _hm.GetProductPartBindList(key);     //_hm為數據庫操作類實例,而GetProductPartBindList(key)則用於反回數據庫查詢的結果
14                 int m = list.Count;
15                 int n = listPec.Count;   //這裡記錄一下靜態BindingList<T>的集合Count值(添加前)
16                 bool flag = false;
17                 if (m > 0)
18                 {
19                     for (int i = 0; i < m; i++)
20                     {
21                         if (listPec.Count > 0)
22                         {
23                             for (int j = 0; j < listPec.Count; j++)
24                             {
25                                 //if (!listPec.Contains(list[i]))   //此去重的方法有BUG,無法正確識別相同項
26                                 if (listPec[j].PartNO.Equals(list[i].PartNO))   //這裡是把不同的記錄添加進去,由於PartNO是主鍵,所以對比這一項就可以了。
27                                     flag = true;
28                             }
29                             if (flag != true)
30                                 //listPec.AddRange(list);
31                                 listPec.Add(list[i]);
32                             flag = false;
33                         }
34                         else
35                         {
36                             //如為零,直接添加
37                             listPec.Add(list[i]);
38                         }
39                     }   
40                 }
41                 
42                 gvData.DataSource = listPec;
43                 //當有新項被添加時,自動將添加的新項打上勾
44                  if (n <listPec.Count) //當n少於listPec.Count的值時,表示,剛才的點擊事件產生了新的記錄,這時,可以把最後一項勾選上。
45                     gvData.Rows[listPec.Count - 1].Cells[0].Value = 1;
46  
47                 //這個不符合功能需求,去掉了。
48                 //遍歷row,把所有位於第一位的CHECKBOX值設為1(即選中狀態)
49                 //foreach (DataGridViewRow row in gvData.Rows)
50                 //{
51                 //    row.Cells[0].Value = 1;
52                 //}
53             }
54         }
原文地址:https://www.cnblogs.com/seasons1987/p/2568408.html