2008-08-02 54 views
43

Giả sử bạn đang làm một cái gì đó như sauWinForms ComboBox dữ liệu ràng buộc Gotcha

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 

Vì vậy, bây giờ chúng tôi có 2 hộp combo liên kết với mảng đó, và tất cả mọi thứ hoạt động tốt. Nhưng khi bạn thay đổi giá trị của một hộp kết hợp, nó sẽ thay đổi BOTH hộp kết hợp thành một trong những bạn vừa chọn.

Bây giờ, tôi biết rằng Mảng luôn được chuyển bằng tham chiếu (đã học được rằng khi tôi học C: D), nhưng tại sao các hộp kết hợp lại thay đổi cùng nhau? Tôi không tin rằng điều khiển hộp kết hợp đang thay đổi bộ sưu tập.

Là một công trình xung quanh, không điều này sẽ đạt được funcionality rằng dự kiến ​​/ mong muốn

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

Trả lời

36

này đã làm với cách liên kết dữ liệu được thiết lập trong khuôn khổ dotnet, đặc biệt là BindingContext. Ở mức độ cao, điều đó có nghĩa là nếu bạn chưa chỉ định cách khác, mỗi biểu mẫu và tất cả các điều khiển của biểu mẫu sẽ chia sẻ cùng một số BindingContext. Khi bạn đang đặt thuộc tính DataSource, ComboBox sẽ sử dụng BindingContext để nhận được ConcurrenyMangager kết thúc tốt nhất danh sách. ConcurrenyManager theo dõi những thứ như vị trí được chọn hiện tại trong danh sách.

Khi bạn đặt DataSource của thứ hai ComboBox nó sẽ sử dụng cùng một BindingContext (hình thức) mà sẽ mang lại một tham chiếu đến cùng ConcurrencyManager sử dụng như trên để thiết lập các ràng buộc dữ liệu.

Để xem giải thích chi tiết hơn, hãy xem BindingContext.

+1

Có vẻ như rất nhiều nỗ lực để không mang lại lợi ích và kiểm soát ràng buộc dữ liệu hoàn toàn chống lại trực quan. – Belmiris

19

Cách giải quyết tốt hơn (tùy thuộc vào kích thước của nguồn dữ liệu) là khai báo hai đối tượng BindingSource (mới là 2.00) liên kết bộ sưu tập với các đối tượng đó và sau đó liên kết chúng với combobox.

Tôi kèm theo một ví dụ hoàn chỉnh.

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); 
     } 
    } 
} 

Nếu bạn muốn tự nhầm lẫn nhiều hơn thì hãy thử luôn khai báo các ràng buộc trong hàm tạo. Điều đó có thể dẫn đến một số lỗi thực sự là , do đó tôi luôn ràng buộc trong sự kiện Tải.

+1

Cảm ơn bạn đã chỉ ra rằng sự ràng buộc trong constructor dẫn đến một số lỗi thực sự tò mò. Tôi đã có một vấn đề tương tự và tôi đã chuyển mã của tôi đến sự kiện Load và nó cho thấy dữ liệu bị ràng buộc. – bunggo

+0

Tôi đã tìm thấy một số lỗi không được báo cáo lạ lùng nhất với điều đó. Trường hợp xấu nhất là một combobox từ chối tập trung lại cho bất kỳ điều khiển nào khác: D – Quibblesome

1

này có thể chỉ là một lỗi đánh máy, nhưng trong các mã mà bạn cung cấp bạn chỉ tham khảo các combo box đầu tiên khi thiết lập các nguồn dữ liệu:

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

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

Các nguồn dữ liệu cho box2 không được thiết lập.

Các vấn đề liên quan