Проблемы виртуализации данных WPF - PullRequest
2 голосов
/ 04 августа 2011

Мне нужно отобразить около нескольких миллионов элементов в WPF ListBox (я знаю, насколько это плохая идея, но я должен сделать это так). Новые элементы поступают очень быстро, тысячи в секунду, но кроме этого в список не вносятся изменения: элементы никогда не удаляются и не изменяются. Мне нужно, чтобы элемент управления LisBox обновлялся хотя бы раз в секунду.

Я понимаю, что я получаю виртуализацию пользовательского интерфейса "бесплатно" в WPF (я использую VirtualizedStackPanel в режиме Recycle и отложенную прокрутку), но я должен виртуализировать данные. Я совершенно новичок в WPF, поэтому я попытался использовать лучшее существующее решение , которое я нашел. Это работает, но мигает каждый раз, когда счет обновляется, и SelectedItem теряется при каждой перезагрузке (я предполагаю, что это происходит потому, что он запускает CollectionChanged типа «Reset», который перезагружает всю коллекцию). Я попытался использовать событие «Добавить» вместо «Сброс», но для этого требуется список элементов, которые фактически были добавлены в коллекцию, и на самом деле не имеет никакого смысла выбирать несколько тысяч объектов в секунду, просто чтобы передать их событию и выбросить их, потому что они все равно виртуализированы. Я также попытался просто запустить свойство PropertyChanged для Count, чтобы ListBox обновил свой диапазон индекса / отрегулировал полосу прокрутки, начались странные вещи: полоса прокрутки адаптировалась бы к новому количеству, хотя элементы списка не отображались и все еще много мерцания.

Другими словами: как мне сообщить элементу управления ListBox, что N новые элементы были добавлены в связанную коллекцию, чтобы ListBox просто настраивал диапазон полосы прокрутки (и не спрашивал меня о добавленные элементы, пока они на самом деле не отображаются).

В этом проекте я использую .NET 4.0 и Caliburn.Micro, но сомневаюсь, что это повлияет на возможные решения.

Ответы [ 2 ]

4 голосов
/ 04 августа 2011

У меня была похожая ситуация, когда мой кэшированный список объектов (в миллионах) был привязан к нескольким спискам в разных приложениях (загружен на разные страницы), и когда кэшированный элемент был добавлен, удален или отредактирован, мне пришлось сохранить выбор и обновлять изменения в приложении без мерцания или прокрутки.

Я реализовал это так ...

  1. Я получил потокобезопасный ObservableCollection с именем FastObservableCollection ... Обновление ObservableCollection в отдельном потоке

  2. Я добавил поддержку AddRange() в вышеупомянутом FastObservaleCollection для массовых вставок без CollectionChanged Уведомлений. CollectionChanged уведомление будет срабатывать ТОЛЬКО один раз для последнего добавленного элемента из массива .... http://peteohanlon.wordpress.com/2008/10/22/bulk-loading-in-observablecollection/

  3. Используется потокобезопасно CollectionViews. Вы можете настроить представление коллекции и отправить событие SourceCollection.CollectionChanged в правильном потоке, вызвав пользовательское событие «Обновление».

Эта ссылка содержит руководство по отправке уведомления об изменении коллекции ... Где получить поточно-безопасный CollectionView?

  1. Я изменил свои ListBoxes для использования привязок SelectedValue вместо SelectedItem привязки и убедился, что SelectedValue является примитивным типом (типом значения). Это поддерживает выбор по значению.

  2. Я бы вызвал ListBox.SelectedValue связывающее выражение UpdateSource() и UpdateTarget(), когда ListBox ItemsSource, т.е. пользовательское событие обновления, вызванное из CollectionView, обрабатывается с помощью присоединенного поведения.

Теперь он работает как шарм без каких-либо добавок и поддерживает выбор.

0 голосов
/ 04 августа 2011

вам нужно создать пользовательскую коллекцию, которая реализует неуниверсальный интерфейс IList, а также универсальный IList. Если вы сделаете это, то элемент управления listbox не будет перечислять коллекцию, но будет использовать интерфейс this [], который даст вам возможность автоматически загружать строки в стиле постраничной подкачки при прокрутке пользователя.

Вот аналогичное решение, которое я разместил в своем блоге: http://www.deanchalk.me.uk/post/WPF-e28093-DataContext-Virtualization-With-Paged-Services.aspx

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