2009-09-17 125 views
5

ComboBox Items集合是一個ObjectCollection,所以當然你可以在其中存儲任何你想要的東西,但這意味着你不會像使用ListViewItem那樣得到一個Text屬性。 ComboBox通過在每個項目上調用ToString()來顯示項目,或者如果設置了DisplayMember屬性,則使用反射來顯示項目。如何刷新組合框項目?

我的組合框處於DropDownList模式。我有一種情況,當用戶選擇它時,我想刷新列表中單個項目的項目文本。問題是ComboBox不會在加載時隨時重新查詢文本,除了刪除和重新添加所選項目之外,我無法弄清楚除了我想要做什麼之外,還有其他方法如何:


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

此代碼工作正常,除了我的SelectedIndex事件最終被解僱了兩次(一次在原始用戶事件,然後當我再次重新設置該屬性在此的代碼)。在這種情況下,事件被觸發兩次並不是什麼大事,但效率很低,而且我討厭這個。我可以製作一面旗幟,以便第二次退出事件,但這是黑客行爲。

有沒有更好的方法來使這個工作?

回答

2

明白了,使用甜甜圈的建議。

在窗體類:

private BindingList<PlantComboBoxItem> _plantList;

在加載方法:

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

在SelectedIndexChanged事件:

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

謝謝!

+0

順便說一句,我不知道爲什麼沒有人想到,包括像在組合框一個RefreshItem功能。 – 2009-09-17 18:02:56

+0

Noooooo ... ResetItem()激發SelectedIndexChanged方法:( 噢,這仍然是我的原始解決方案更清潔。 – 2009-09-17 18:13:54

+0

您是否需要調用ResetItem()'?如果您需要更改'cboPlants'中的項目只是直接更新它(我認爲?)。你可以在'SelectedIndexChanged'事件中用'_plantList [selectedIndex]'來訪問它。 – Donut 2009-09-17 21:17:07

4

嗯...你能否使用BindingList<T>,如here所述?這樣,您可以修改底層集合中的項目,並將其反映在ComboBox中,而無需在控件中添加或刪除任何內容。

你需要有一個集合這樣的事情,包含的ComboBox您的所有項目:

private BindingList<PlantComboBoxItem> plantComboBoxItems; 

然後,在某些時候(當程序啓動等),將其綁定到ComboBox

cboPlants.DataSource = plantComboBoxItems; 

現在,你可以直接修改集合:

plantComboBoxItems[cboPlants.SelectedIndex].doWhateverYouWant(); 

而變化將反映在cboPlants。這是你在找什麼?

8

一個骯髒的黑客:

typeof(ComboBox).InvokeMember("RefreshItems", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, cboPlants, new object[] { });