2009-09-17 20 views
5

Bộ sưu tập ComboBox Items là một ObjectCollection, vì vậy tất nhiên bạn có thể lưu trữ bất cứ thứ gì bạn muốn trong đó, nhưng điều đó có nghĩa là bạn không có được một thuộc tính Text giống như bạn làm với một ListViewItem. ComboBox hiển thị các mục bằng cách gọi ToString() trên mỗi mục hoặc sử dụng phản chiếu nếu thuộc tính DisplayMember được đặt.Làm cách nào để bạn làm mới mục hộp tổ hợp tại chỗ?

ComboBox của tôi ở chế độ DropDownList. Tôi có một tình huống mà tôi muốn làm mới mục văn bản của một mục duy nhất trong danh sách khi nó được chọn bởi người dùng. Vấn đề là ComboBox không truy vấn lại văn bản bất cứ lúc nào bên cạnh khi nó tải lên và tôi không thể tìm ra cách khác để thực hiện những gì tôi muốn ngoài việc xóa và thêm lại mục đã chọn như vậy:


PlantComboBoxItem selectedItem = cboPlants.SelectedItem as PlantComboBoxItem; 

// ... 

cboPlants.BeginUpdate(); 

int selectedIndex = cboPlants.SelectedIndex; 
cboPlants.Items.RemoveAt(selectedIndex); 
cboPlants.Items.Insert(selectedIndex, selectedItem); 
cboPlants.SelectedIndex = selectedIndex; 

cboPlants.EndUpdate(); 

mã này hoạt động tốt, ngoại trừ một thực tế rằng sự kiện SelectedIndex của tôi kết thúc lên bị sa thải hai lần (một lần vào trường hợp sử dụng ban đầu, và sau đó một lần nữa khi tôi tái thiết lập thuộc tính trong mã này). Trong trường hợp này, nó không phải là một vấn đề lớn mà sự kiện được bắn hai lần, nhưng nó không hiệu quả, và tôi ghét điều đó. Tôi có thể dựng lên một lá cờ để nó thoát khỏi sự kiện lần thứ hai, nhưng đó là hack.

Có cách nào tốt hơn để làm việc này không?

Trả lời

2

OK, sử dụng đề xuất của Donut.

Trong lớp có dạng:

private BindingList<PlantComboBoxItem> _plantList;

Trong phương pháp tải:

_plantList = new BindingList<PlantComboBoxItem>(plantItems); 
cboPlants.DataSource = _plantList;

Trong sự kiện SelectedIndexChanged:

int selectedIndex = cboPlants.SelectedIndex; 
_plantList.ResetItem(selectedIndex);

Cảm ơn bạn!

+0

Là một sang một bên, tôi tự hỏi tại sao không ai nghĩ tới bao gồm một cái gì đó giống như một chức năng RefreshItem trên ComboBox. –

+0

Noooooo ... ResetItem() kích hoạt phương thức SelectedIndexChanged: ( Ồ, điều này vẫn còn sạch hơn là giải pháp ban đầu của tôi. –

+0

Bạn có cần gọi 'ResetItem()'? Mục trong 'cboPlants' nên được thay đổi nếu bạn chỉ cần cập nhật nó trực tiếp (tôi nghĩ?).Bạn có thể truy cập nó trong sự kiện 'SelectedIndexChanged' với' _plantList [selectedIndex] '. – Donut

4

Hmm ... bạn có thể sử dụng số BindingList<T>, như được mô tả here không? Bằng cách đó, bạn chỉ có thể sửa đổi các mục trong bộ sưu tập cơ bản và có nó phản ánh trong ComboBox mà không cần phải thêm hoặc loại bỏ bất cứ điều gì từ kiểm soát.

Bạn sẽ cần phải có một cái gì đó bộ sưu tập như thế này, có chứa tất cả các mục của bạn cho ComboBox:

private BindingList<PlantComboBoxItem> plantComboBoxItems; 

Sau đó, tại một số điểm (như khi chương trình được bắt đầu), ràng buộc nó vào ComboBox :

cboPlants.DataSource = plantComboBoxItems; 

Bây giờ, bạn chỉ có thể sửa đổi các bộ sưu tập trực tiếp:

plantComboBoxItems[cboPlants.SelectedIndex].doWhateverYouWant(); 

Và thay đổi sẽ được phản ánh trong cboPlants. Đây có phải là những gì bạn đang tìm kiếm không?

8

Một bẩn hack:

typeof(ComboBox).InvokeMember("RefreshItems", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, cboPlants, new object[] { }); 
Các vấn đề liên quan