2009-09-17 8 views
5

La colección de elementos de ComboBox es una colección de objetos, por lo que puede almacenar lo que desee allí, pero eso significa que no obtendrá una propiedad de texto como lo haría con, por ejemplo, un ListViewItem. ComboBox muestra los elementos llamando a ToString() en cada elemento o utilizando el reflejo si se establece la propiedad DisplayMember.¿Cómo se actualiza un elemento del cuadro combinado en el lugar?

Mi ComboBox está en modo DropDownList. Tengo una situación en la que quiero actualizar el texto del elemento de un solo elemento en la lista cuando es seleccionado por el usuario. El problema es que el ComboBox no vuelve a consultar el texto en ningún momento, además de cuando se carga, y no puedo entender cómo hacer lo que quiero, además de eliminar y volver a agregar el elemento seleccionado así:


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

este código funciona bien, excepto por el hecho de que mi caso SelectedIndex termina siendo despedido dos veces (una vez en el evento de usuario original, y luego otra vez cuando me re-establecer la propiedad en el código). En este caso, no es gran cosa que el evento se dispare dos veces, pero es ineficiente, y odio eso. Podría armar una bandera para que salga del evento la segunda vez, pero eso es piratería.

¿Hay alguna forma mejor de hacer que esto funcione?

Respuesta

2

Lo tengo, utilizando la sugerencia de Donut.

En la clase de formulario:

private BindingList<PlantComboBoxItem> _plantList;

En el método de carga:

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

En caso SelectedIndexChanged:

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

Gracias!

+0

Como acotación al margen, me pregunto por qué nadie pensó en incluir algo así como una función RefreshItem en el cuadro combinado. –

+0

Noooooo ... ResetItem() desencadena el método SelectedIndexChanged :( Oh, bueno, esto es aún más limpio que mi solución original. –

+0

¿Necesita llamar a 'ResetItem()'? El elemento en 'cboPlants' debe cambiarse si simplemente actualizarlo directamente (¿creo?).Puede acceder a él en el evento 'SelectedIndexChanged' con' _plantList [selectedIndex] '. – Donut

4

Hmm ... ¿podría usar un BindingList<T>, como se describe here? De esta forma, puede modificar el elemento en la colección subyacente y hacer que se refleje en el ComboBox sin tener que agregar o eliminar nada del control.

que había necesidad de tener una colección algo como esto, que contiene todos los elementos para el ComboBox:

private BindingList<PlantComboBoxItem> plantComboBoxItems; 

entonces, en algún momento (como cuando el programa está empezando), se unen a la ComboBox :

cboPlants.DataSource = plantComboBoxItems; 

Ahora, sólo puede modificar la colección directamente:

plantComboBoxItems[cboPlants.SelectedIndex].doWhateverYouWant(); 

Y los cambios se reflejarán en cboPlants. Es esto lo que estás buscando?

8

Un truco sucio:

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