WPF привязывает список / коллекцию элементов к ListBox, но пользовательский интерфейс не обновляется после обновления элементов, Решено .
Я просто тупой. Хотя я много читал об использовании ObservableCollection<>
вместо List<>
, я просто продолжал игнорировать это предложение и следовал другим советам, но безрезультатно. Вернулся к моим книгам и перечитал. Довольно хорошо объяснено, что ObservableCollection<>
является обязательным для использования, потому что List<>
не предоставляет интерфейс INotifyCollectionChange
, необходимый для ListBox
для обновления отображения при изменении элементов в коллекции.
Это обновленный код:
private ObservableCollection<StringWrapper> m_AppLog;
ObservableCollection<StringWrapper> Log { get { return m_AppLog; } }
Довольно просто и не требует ничего другого (например, Refresh ()). Поскольку ObservableCollection заботится о срабатывании события изменения, я смог удалить ненужный вызов:
// notify bound objects
OnPropertyChanged("Log");
ObservableCollection
не поддерживает обновление тем, которые его не создавали. Поскольку мой список (визуальный журнал для отображения недавних сообщений об ошибках / информационных сообщениях) можно обновлять из разных потоков, я добавляю его, чтобы настроить свой код таким образом, чтобы гарантировать, что обновление было выполнено с собственным диспетчером списка:
public void AddToLog(string message) {
if (Thread.CurrentThread != Dispatcher.Thread) {
// Need for invoke if called from a different thread
Dispatcher.Invoke(
DispatcherPriority.Normal, (ThreadStart)delegate() { AddToLog(message); });
}
else {
// add this line at the top of the log
m_AppLog.Insert(0, new StringWrapper(message));
// ...
Также обратите внимание, что ObservableCollection<>
не поддерживает RemoveRange()
вопреки List<>
. Это часть возможных корректировок, требуемых при переходе от List к ObservableCollection.