zoukankan      html  css  js  c++  java
  • 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         }
  • 相关阅读:
    Condition控制线程通信
    Lock同步锁
    通过Callable接口创建线程
    CountDownLatch闭锁
    CopyOnWriteArrayList笔记
    原子变量与CAS算法
    Java网络编程之UDP
    Java网络编程之Socket
    Java网络编程之URLConnection
    Java中处理异常中return关键字
  • 原文地址:https://www.cnblogs.com/seasons1987/p/2568408.html
Copyright © 2011-2022 走看看