В нашем приложении TreeView привязан к ObservableCollection, который мы регулярно обновляем в фоновом потоке, запрашивая данные из нашего хранилища. Работает отлично!
Упс. Я был неправильно информирован =))
Правильно, мы фактически подклассифицируем ObservableCollection<T>
и переопределяем метод OnCollectionChanged
, чтобы избежать исключения перекрестного обмена пользовательским интерфейсом. Мы используем это решение :
public class MTObservableCollection<T> : ObservableCollection<T>
{
public override event NotifyCollectionChangedEventHandler CollectionChanged;
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
var eh = CollectionChanged;
if (eh != null)
{
Dispatcher dispatcher = (from NotifyCollectionChangedEventHandler nh in eh.GetInvocationList()
let dpo = nh.Target as DispatcherObject
where dpo != null
select dpo.Dispatcher).FirstOrDefault();
if (dispatcher != null && dispatcher.CheckAccess() == false)
{
dispatcher.Invoke(DispatcherPriority.DataBind, (Action)(() => OnCollectionChanged(e)));
}
else
{
foreach (NotifyCollectionChangedEventHandler nh in eh.GetInvocationList())
nh.Invoke(this, e);
}
}
}
}
Без этого переопределения вы получите вот такое исключение
System.NotSupportedException: это
Тип CollectionView не
поддержать изменения в его
SourceCollection из потока
отличается от темы Dispatcher.
Теперь единственной проблемой, с которой мы сталкиваемся, является позиция выбранного элемента, в некоторых случаях, если текущий выбранный элемент удаляется из коллекции, TreeView перемещает выбор к следующему элементу (что вызывает некоторые другие ненужные действия пользовательского интерфейса в нашем приложении). Но это небольшая проблема.