2008-08-02 114 views
43

假設你正在做類似下面的WinForms組合框的數據綁定的疑難雜症

List<string> myitems = new List<string> 
{ 
    "Item 1", 
    "Item 2", 
    "Item 3" 
}; 

ComboBox box = new ComboBox(); 
box.DataSource = myitems; 

ComboBox box2 = new ComboBox(); 
box2.DataSource = myitems 

東西所以現在我們有綁定到陣列2個組合框,一切工作正常。但是,當您更改一個組合框的值時,它會將兩個組合框更改爲您剛選擇的組合框。

現在,我知道數組總是通過引用傳遞的(知道當我學習C:D時),但爲什麼地球上的組合框會一起變化?我不相信組合框控件正在修改集合。

作爲變通,不要這會實現,預計在的funcionality /所需

ComboBox box = new ComboBox(); 
box.DataSource = myitems.ToArray(); 

回答

36

這與數據綁定是如何設立在DOTNET框架,尤其是BindingContext做。在高層次上,這意味着如果您沒有另外指定,則每個表單和表單的所有控件共享相同的BindingContext。當您設置DataSource屬性時,ComboBox將使用BindingContext獲取包裝列表的ConcurrenyMangagerConcurrenyManager跟蹤列表中當前所選位置等事物。

當設置了第二ComboBox它將使用相同BindingContext(形式),這將產生對如上述用於建立數據綁定相同ConcurrencyManager基準的DataSource

要獲得更詳細的解釋,請參見BindingContext

+1

似乎很多努力沒有提供任何好處,並使數據綁定控件完全違反直覺。 – Belmiris 2015-06-01 15:13:45

19

更好的解決方法(取決於數據源的大小)是聲明兩個BindingSource對象(新的2.00)將集合綁定到這些對象,然後將這些對象綁定到組合框。

我附上一個完整的例子。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 

namespace WindowsFormsApplication2 
{ 
    public partial class Form1 : Form 
    { 
     private BindingSource source1 = new BindingSource(); 
     private BindingSource source2 = new BindingSource(); 

     public Form1() 
     { 
      InitializeComponent(); 
      Load += new EventHandler(Form1Load); 
     } 

     void Form1Load(object sender, EventArgs e) 
     { 
      List<string> myitems = new List<string> 
      { 
       "Item 1", 
       "Item 2", 
       "Item 3" 
      }; 

      ComboBox box = new ComboBox(); 
      box.Bounds = new Rectangle(10, 10, 100, 50); 
      source1.DataSource = myitems; 
      box.DataSource = source1; 

      ComboBox box2 = new ComboBox(); 
      box2.Bounds = new Rectangle(10, 80, 100, 50); 
      source2.DataSource = myitems; 
      box2.DataSource = source2; 

      Controls.Add(box); 
      Controls.Add(box2); 
     } 
    } 
} 

如果你想更多地迷惑自己,那麼試着總是在構造函數中聲明綁定。這可能會導致一些真的好奇的錯誤,因此我總是在Load事件中綁定。

+1

感謝您指出在構造函數中的綁定導致一些真正好奇的錯誤。我有一個類似的問題,我將我的代碼移動到Load事件,它顯示了綁定的數據。 – bunggo 2013-10-08 19:47:27

1

這可能只是一個錯字,但在你的代碼提供你只設置數據源時引用的第一個組合框:

ComboBox box = new ComboBox(); 
box.DataSource = myitems; 

ComboBox box2 = new ComboBox(); 
**box**.DataSource = myitems 

box2數據源未設置。