之前沒怎麼用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 }