2009-09-17 14 views
5

Kolekcja ComboBox Items jest ObjectCollection, więc oczywiście możesz przechowywać w niej wszystko, co chcesz, ale to oznacza, że ​​nie otrzymasz właściwości Text, jak w przypadku, powiedzmy, ListViewItem. ComboBox wyświetla elementy, wywołując ToString() na każdym elemencie lub używając odbicia, jeśli właściwość DisplayMember jest ustawiona.Jak odświeżyć element pola kombi w miejscu?

Mój ComboBox jest w trybie DropDownList. Mam sytuację, w której chcę odświeżyć tekst pozycji pojedynczego elementu na liście, gdy zostanie wybrany przez użytkownika. Problem polega na tym, że ComboBox nie przesyła ponownie zapytania do tekstu w żadnym momencie, oprócz tego, kiedy ładuje się, i nie mogę wymyślić, jak inaczej robić, co chcę oprócz usunięcia i ponownego dodania wybranego elementu, jak na przykład:


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

Ten kod działa poprawnie, z wyjątkiem faktu, że moja impreza SelectedIndex kończy się wyrzucenie dwa razy (raz na oryginalnym zdarzenia użytkownika, a następnie ponownie, kiedy ponownie ustawić właściwość w tym kodzie). W tym przypadku nie jest to wielka sprawa, że ​​wydarzenie jest uruchamiane dwa razy, ale jest nieefektywne i nienawidzę tego. Mógłbym ustawić flagę tak, aby opuściła to wydarzenie po raz drugi, ale to hackowanie.

Czy istnieje lepszy sposób, aby to zadziałało?

Odpowiedz

2

Rozumiem, używając sugestii Donuta.

W klasie forma:

private BindingList<PlantComboBoxItem> _plantList;

W metodzie ładunkowej:

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

W przypadku SelectedIndexChanged:

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

Dziękujemy!

+0

Tak na marginesie, zastanawiam się dlaczego nikt nie pomyślał, aby to coś w rodzaju funkcji RefreshItem na ComboBox. –

+0

Noooooo ... ResetItem() uruchamia metodę SelectedIndexChanged :( No cóż, to jest jeszcze czystsze niż moje oryginalne rozwiązanie –

+0

Czy musisz wywołać 'ResetItem()'? Element w 'cboPlants' powinien zostać zmieniony, jeśli po prostu zaktualizuj go bezpośrednio (chyba?).Możesz uzyskać do niego dostęp w zdarzeniu 'SelectedIndexChanged' za pomocą' _plantList [selectedIndex] '. – Donut

4

Hmm ... czy można użyć numeru BindingList<T>, zgodnie z opisem here? W ten sposób możesz po prostu zmodyfikować element w podstawowej kolekcji i mieć to odzwierciedlenie w ComboBox bez konieczności dodawania lub usuwania czegokolwiek z formantu.

trzeba by mieć zbiór coś takiego, zawierający wszystkie elementy dla ComboBox:

private BindingList<PlantComboBoxItem> plantComboBoxItems; 

Następnie, w pewnym momencie (jak wtedy, gdy program zaczyna), wiążą go do ComboBox :

cboPlants.DataSource = plantComboBoxItems; 

teraz można po prostu zmodyfikować kolekcję bezpośrednio:

plantComboBoxItems[cboPlants.SelectedIndex].doWhateverYouWant(); 

Zmiany zostaną odzwierciedlone w cboPlants. Czy tego właśnie szukasz?

8

Brudny Hack:

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