WPF ICollectionView.filter с большими наборами данных - PullRequest
24 голосов
/ 12 мая 2009

Я работаю над приложением wpf, которое содержит просмотр списка с большим количеством строк данных (от 10 000 до 100 000). Пользователь может применять всевозможные фильтры к этому списку, что делает логику фильтра довольно продвинутой (и медленной). На данный момент соответствующая часть моего кода выглядит так:

ICollectionView view = CollectionViewSource.GetDefaultView(hugeList.ItemsSource);
view.Filter = new Predicate<object>(FilterCallback);

private bool FilterCallback(object item)
{
  //Filter logic
}

Но это выполняется в потоке пользовательского интерфейса и блокирует все приложение при фильтрации, что дает очень плохой пользовательский опыт. Поэтому мой вопрос ко всем вам: знает ли кто-нибудь «лучший» способ фильтрации списка в wpf, или я должен вместо этого фильтровать базовый ObservableCollection?

Ответы [ 2 ]

21 голосов
/ 12 мая 2009

Обратите пристальное внимание на вашу функцию фильтра. Убедитесь, что вы не занимаетесь ненужным боксом / распаковкой и не проводите в нем обширных вычислений. Вы также должны обратить внимание на то, какой тип CollectionView вы используете, некоторые быстрее, чем другие. Из сообщения Беа о сортировке :

  • A CollectionView создается, если ваш источник реализует IEnumerable. Если источник реализует IEnumerable only , вы не сможете отсортировать или сгруппировать коллекцию (вы можете только отфильтровать ее). Кроме того, perf не будет наилучшим, если в источнике содержится большое количество элементов или если вы выполняете динамические операции, такие как вставки и удаления. Если это ваш сценарий, вам следует подумать о том, чтобы ваш источник реализовал более сильный интерфейс. ICollection немного лучше, поскольку предоставляет свойство Count.

  • ListCollectionView - это тип представления, созданный, когда источник реализует IList. По сравнению с IEnumerable и ICollection, IList работает намного лучше для больших или динамических списков, поскольку предоставляет индексатор, позволяющий нам быстрый произвольный доступ. Кроме того, IList позволяет сортировать, группировать и фильтровать. Но в идеале ваша исходная коллекция происходит от ObservableCollection, прародителя всех коллекций с точки зрения привязки данных, поскольку она предоставляет несколько дополнительных полезностей, таких как уведомления об изменениях свойств и коллекций.

  • BindingListCollectionView - это тип представления, созданный Avalon, когда исходная коллекция реализует IBindingList. Это представление, с которым мы имеем дело в сценарии ADO.NET. Поддерживает сортировку и группировку, но не традиционную фильтрацию. Вместо этого у него есть дополнительное свойство CustomFilter, которое делегирует фильтрацию в DataView (подробнее см. Мой пост в ADO.NET).

Вы можете запустить фильтрацию в другом потоке, как сказал @mihi, но я использовал CollectionViews для одновременного запуска нескольких фильтров на ObservableCollection с 50 000 элементов на объекте с ~ 60 переменными (столбцами в таблице базы данных) без заметной задержки.

Одна вещь, которую я сразу замечаю в вашей функции фильтра, это то, что ввод имеет тип Object, что, вероятно, означает, что вы выполняете преобразование типа внутри функции и, возможно, вам это не нужно. Вы также используете Predicate, который не включает тип возвращаемого значения, так что, вероятно, требуются некоторые преобразования типов или отражения в методах фильтрации CollectionView, что также может замедлить работу.

3 голосов
/ 12 мая 2009

Рассматривали ли вы фильтрацию в другом потоке или использование диспетчера?

Потоки WPF: Создавайте более отзывчивые приложения с помощью диспетчера дает вам хороший обзор некоторых доступных вам вариантов потоков.

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