Как обновить элемент комбинированного окна на месте? - PullRequest
5 голосов
/ 17 сентября 2009

Коллекция ComboBox Items представляет собой ObjectCollection, поэтому, конечно, вы можете хранить там все, что захотите, но это означает, что вы не получите свойство Text, как, например, с ListViewItem. ComboBox отображает элементы, вызывая ToString () для каждого элемента или используя отражение, если установлено свойство DisplayMember.

Мой ComboBox находится в режиме 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 завершается тем, что его запускают дважды (один раз для исходного пользовательского события, а затем снова, когда я повторно устанавливаю свойство в этом коде). В этом случае не имеет большого значения, что событие запускается дважды, но оно неэффективно, и я ненавижу это. Я мог бы установить флаг, чтобы он выходил из события во второй раз, но это взлом.

Есть ли лучший способ заставить это работать?

Ответы [ 3 ]

8 голосов
/ 25 января 2012

Грязный хак:

typeof(ComboBox).InvokeMember("RefreshItems", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, cboPlants, new object[] { });
4 голосов
/ 17 сентября 2009

Хмм ... не могли бы вы использовать BindingList<T>, как описано здесь ? Таким образом, вы можете просто изменить элемент в базовой коллекции и отразить его в ComboBox без добавления или удаления чего-либо из элемента управления.

Вам понадобится такая коллекция, содержащая все ваши предметы для ComboBox:

private BindingList<PlantComboBoxItem> plantComboBoxItems;

Затем, в какой-то момент (например, при запуске программы), свяжите его с ComboBox:

cboPlants.DataSource = plantComboBoxItems;

Теперь вы можете просто изменить коллекцию напрямую:

plantComboBoxItems[cboPlants.SelectedIndex].doWhateverYouWant();

И изменения будут отражены в cboPlants. Это то, что вы ищете?

2 голосов
/ 17 сентября 2009

Понял, пользуясь предложением пончика.

В классе:

private BindingList<PlantComboBoxItem> _plantList;

В способе загрузки:

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

В событии SelectedIndexChanged:

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

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...