Элемент списка .NET WinForm ListBox отображает старое значение до тех пор, пока не будет переназначено самому себе - PullRequest
2 голосов
/ 18 февраля 2010

Я заполняю элемент управления ListBox моими собственными объектами, переопределяя ToString (). Объекты отображаются правильно, когда я просто добавляю эти объекты, используя listBox1.Add (myObject). Однако, если я позже что-то изменю в этом объекте, никакие изменения не отображаются в списке. Отладка показывает, что объект внутри listBox1.Items действительно изменен, но он не отображается на экране.

Интересно, что если я переназначу определенный элемент списка себе (звучит немного странно, не правда ли?), Например:

listBox1.Items[0] = listBox1.Items[0]

эта строка будет отображать правильное значение на экране.

Что здесь происходит? Это как-то связано с потоками?

Ответы [ 4 ]

3 голосов
/ 18 февраля 2010

Поскольку вы используете ToString объекта для предоставления текста элемента списка, ListBox не знает, что значение изменилось. Вместо этого вы должны сделать так, чтобы объект осуществлял INotifyPropertyChanged , затем предоставлял открытое свойство, такое как Имя или Текст, и возвращал то, что вы обычно возвращали бы из ToString ().

Затем установите DisplayMember в ListBox на имя нового свойства.

Убедитесь, что вы правильно вызываете событие PropertyChanged в объекте, и ListBox должен иметь возможность автоматически получать изменения.

Редактировать. Редактирование Адриана напомнило мне, что я считаю, что вам нужно использовать BindingList в качестве источника данных для получения уведомлений об изменении свойства. Быстрое сканирование в Reflector похоже на то, что ListBox сам по себе не обнаружит изменения свойств, упомянутые выше. Но INotifyPropertyChanged + BindingList должен.

2 голосов
/ 18 февраля 2010

Значение ToString() каждого элемента кэшируется при первом отображении списка. Если элемент в коллекции Items списка затем изменяется, список не замечает и все еще использует кэшированные значения ToString() для отображения. Чтобы принудительно обновить список, вызовите RefreshItems(), чтобы обновить все элементы, или вызовите RefreshItem(int), указав индекс элемента для обновления.

Из документов MSDN для RefreshItems():

Обновляет все элементы ListBox и получает для них новые строки.


РЕДАКТИРОВАТЬ: Оказывается, что оба эти метода защищены, поэтому не могут быть вызваны извне. Пытаясь найти решение, я наткнулся на этот ТАК вопрос , что этот вопрос в основном является дубликатом.

0 голосов
/ 18 февраля 2010

Вы пытались позвонить Refresh() в ListBox? Я думаю, что проблема в том, что ListBox не знает, что ваш объект изменился. Причина переназначения элемента работает потому, что ListBox перекрашивается при изменении коллекции.

0 голосов
/ 18 февраля 2010

Вы можете сделать недействительным элемент управления, заставив перерисовать ... возможно ..

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