Winform Combox出現"System.Data.DataRowView"問題得的解決方法

原文鏈接:https://www.cnblogs.com/hrhguanli/p/3780346.html

原文轉載於:https://www.cnblogs.com/hrhguanli/p/3780346.html

谷歌答案:

 

當使用Combobox控件時,出現SelectedValue的值爲“System.Data.DataRowView”的原因有兩個:在Combobox的DataSource不爲空的情況下,要麼是沒有爲ValueMember賦值,要麼是賦值賦錯了,這兩種情況下系統就會把SelectedValue的默認值輸出來(注意紅色部分,假設DataSource爲空,那麼SelectedValue的值爲null)。但有時即使你對ValueMember賦了正確的值也會出現這個問題,這裏有一個賦值時機選擇的問題,請看以下的演示樣例:

       首先,構造例如以下所看到的的一個窗口:

       

窗口有一個下拉框,名爲Combobox1,另一個文本框,名爲TextBox1,功能非常easy,當選擇下拉框的某一項的時候,把該選擇項相應的ValueMember的值顯示到文本框中。以下是實現該功能的核心代碼:

Code-1:

 

[c-sharp] view plaincopy

  1. namespace FrmForTest  
  2. {  
  3.     public partial class Form1 : Form  
  4.     {  
  5.         public Form1()  
  6.         {  
  7.             InitializeComponent();  
  8.             this.InitialCombobox();  
  9.         }  
  10.   
  11.         private void InitialCombobox()  
  12.         {  
  13.             DataTable table = new DataTable();  
  14.             DataColumn column;  
  15.             DataRow row;  
  16.   
  17.             column = new DataColumn("Name");  
  18.             table.Columns.Add(column);  
  19.   
  20.             column = new DataColumn("Value");  
  21.             table.Columns.Add(column);  
  22.   
  23.             for (int i = 0; i < 5; i++)  
  24.             {  
  25.                 row = table.NewRow();  
  26.                 row["Name"] = "Test" + i;  
  27.                 row["Value"] = i.ToString();  
  28.                 table.Rows.Add(row);  
  29.             }  
  30.   
  31.             this.comboBox1.DataSource = table;  
  32.             this.comboBox1.DisplayMember = "Name";  
  33.             this.comboBox1.ValueMember = "Value";  
  34.         }  
  35.   
  36.         private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)  
  37.         {  
  38.             this.textBox1.Text = this.comboBox1.SelectedValue.ToString();  
  39.         }  
  40.     }  
  41. }  

 

執行上面的代碼,窗口初始化完成後輸出的結果例如以下:

 

文本框顯示的是“System.Data.DataRowView”,前面說過,僅僅有在沒有爲Combobox指定ValueMember的值或指定錯的情況下才會是該字符串,可程序已經正確指定了ValueMember爲什麼還是這個結果呢?我試着選擇其它的下拉項,發現顯示的結果變成了預想的值,原因何在?

       細緻觀察程序發現原因在於ValueMember賦值的時機,上面的代碼當運行完DataSource賦值語句之後,觸發了SelectedIndexChanged事件,而此時還未指定ValueMember,所以窗口初次初始化後顯示的是“System.Data.DataRowView”,解決方法非常easy:僅僅需把DataSource賦值語句放到DisplayMember、ValueMember語句之後。

好,這個問題攻克了,新的問題又來了,請看以下的描寫敘述:

突然想到Combobox另一個事件是SelectedValueChanged,還是上面的程序Code-1,把SelectedIndexChanged替換爲SelectedValueChanged,會是什麼效果呢?試了一下,沒有報錯,而且窗口初始化完成後顯示的就是預期的值0。呵呵,又找到了一種解決方法。問題還沒完,請接着往下看:

上面SelectedValueChanged的試驗中,DataSource是在DisplayMember、ValueMember前面的,假設放到它們兩個後面呢?繼續嘗試,這次報錯了——“未將對象引用到對象的演示樣例”,對程序進行跟蹤,當運行完this.comboBox1.ValueMember = "Value"語句之後,程序轉到了comboBox1_SelectedIndexChanged方法,在this.textBox1.Text = this.comboBox1.SelectedValue.ToString();語句處報錯,SelectedValue的值爲空,由於此時還沒有給DataSource賦值,所以報這個錯。

如今能夠總結了,當使用SelectedIndexChanged時,ValueMember在DataSource前進行賦值,當使用SelectedValueChanged時,ValueMember在DataSource後進行賦值。

另一個問題非常有意思,例如以下所看到的:

this.comboBox1.DisplayMember = "Name";

this.comboBox1.ValueMember = "ValueError";

   this.comboBox1.DataSource = table;

上面有益把ValueMember的值寫錯了,執行起來沒有不論什麼問題(是指沒有報錯,此時的SelectedValue值都爲System.Data.DataRowView),然後我們對這三行代碼的順序做一下調整,例如以下:

   this.comboBox1.DataSource = table;

this.comboBox1.DisplayMember = "Name";

this.comboBox1.ValueMember = "ValueError";

上面ValueMember的值依然是錯的,可是對其賦值操作放到了DataSource語句之後,執行程序,在ValueMember賦值語句處報錯例如以下:“無法綁定到值成員”。

當指定了DataSource的值後再對ValueMember賦錯,假設此時賦值賦錯的話,執行時就會報錯,假設是在DataSource語句之前對ValueMember賦值則不會報錯,大家在應用的時候一定要注意。

 

 

個人總結:

1.觸發了SelectedIndexChanged事件時:comboBox1.DataSource = dt;要放在comboBox1.SelectedIndex = 0;的上面

    
            comboBox1.DisplayMember = "hName";
            comboBox1.ValueMember = "hId";
            comboBox1.DataSource = dt;
            comboBox1.SelectedIndex = 0;

2.觸發了SelectedValueChanged事件時:comboBox1.DataSource = dt;要放在最上面

    comboBox1.DataSource = dt;
            comboBox1.DisplayMember = "hName";
            comboBox1.ValueMember = "hId";
            comboBox1.SelectedIndex = 0;

   並且在 comboBox1_SelectedValueChanged事件中還要加上推斷。

   if (comboBox1.SelectedValue.ToString() == "System.Data.DataRowView") return;
            string selectedHId = comboBox1.SelectedValue.ToString();

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章