Обновление WPF ICollectionView
-
22-07-2019 - |
Вопрос
Есть ли способ, как это сделать
ICollectionView.Refresh()
или
CollectionViewSource.GetDefaultView(args.NewValue).Refresh();
в отдельная тема?
Я знаю, что могу использовать диспетчер, но эта коллекция привязана к ListView и выдает межпотоковые исключения.
Причина, по которой мне нужен второй поток, заключается в том, что у меня есть элемент управления, который отображает список IMyItems.При фильтрации этой коллекции (путем изменения текста пользователя) я хочу иметь возможность отображать анимацию, которую изменяет CollectionView.
Решение
Вы не можете!
Все операции пользовательского интерфейса должны выполняться в потоке пользовательского интерфейса, и почти каждый вызов внутри DispatcherObject WPF (и всех элементов управления в этой иерархии) будет регулярно вызывать CheckAccess ().
Возможно, вы захотите использовать ObservableCollection, чтобы поддерживать актуальность ваших данных, если вы выполняете обработку в фоновом потоке или BackgroundWorker.
Другие советы
Как насчет использования Dispatcher для работы с фоновым приоритетом?
Dispatcher.Invoke(DispatcherPriority.Background,
() => { CollectionViewSource.GetDefaultView(args.NewValue).Refresh(); }
);
Я придумал быстрый метод вызова действий над управляемыми объектами wpf (все элементы управления wpf наследуются от ДиспетчерОбъект)
public static void InvokeWpf(DispatcherObject dispatchable, Action action, bool async)
{
// DispatcherOperationCallback is optimized for wpf invoke calls
DispatcherOperationCallback toDo = delegate{ action(); return null; };
if (!dispatchable.CheckAccess())
{
if (async)
dispatchable.Dispatcher.BeginInvoke(toDo, null);
else
dispatchable.Dispatcher.Invoke(toDo, null);
}
else
{
toDo(null);
}
}
Использование:
InvokeWpf(listView,
() => CollectionViewSource.GetDefaultView(listView).Refresh(),
false);