Что вызывает WPF ListCollectionView, который использует пользовательскую сортировку для обращений ее объектов?

bpf_helpers.h не распространяется с заголовками ядра . Как предложено agg3l в комментариях, вы можете скопировать его из пакета linux-source Ubuntu .

10
задан Drew Noakes 2 March 2009 в 10:46
поделиться

3 ответа

Я нашел эту статью Доктора WPF, который начинается с ответом на мой вопрос, затем идет дальше для обсуждения влияния производительности вызова Refresh. Некоторые ключевые выборки:

К сожалению, Обновление () метод приводит к полной регенерации представления. Когда Обновление () происходит в рамках представления, оно повышает уведомление CollectionChanged и предоставляет Действие как "Сброс". ItemContainerGenerator для ListBox получает это уведомление и отвечает путем отбрасывания всего существующего зрительного ряда для объектов. Это затем полностью повторно создает новые контейнеры объекта и зрительный ряд.

Он затем описывает hacky обходное решение, которое улучшает производительность. Вместо того, чтобы называть Обновление, удалите, изменение затем повторно добавляют объект.

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

Новый подход был представлен в.NET 3,5 SP1, включающие интерфейс IEditableObject это обеспечивает транзакционное редактирование через привязку данных к шаблону с методами BeginEdit(), CancelEdit(), и EndEdit(). Прочитайте статью для получения дополнительной информации.

ОТРЕДАКТИРУЙТЕ, Как user346528 указывает, IEditableObject не было на самом деле новым в 3.5SP1. На самом деле похоже, что это было в платформе с тех пор 1.0.

8
ответ дан 3 December 2019 в 20:06
поделиться

Учитывая, что Вы используете пользовательскую сортировку, нет никакого пути к ListCollectionView знать, какие критерии должны инициировать обновление. Поэтому необходимо будет звонить Refresh() на наборе просматривают себя.

1
ответ дан 3 December 2019 в 20:06
поделиться

Поднимаем старый пост, но просто создаем новый класс коллекции, который наследуется от ListViewCollection и переопределяет OnPropertyChanged (для IBindingList события ListChanged будут содержать изменение свойства в параметре ListChangedEventArgs). И убедитесь, что элементы в коллекции реализуют и используют INotifyPropertyChange всякий раз, когда свойство изменяется (вызывается вами), иначе коллекция не будет привязываться к изменениям свойств.

Тогда в этом методе OnPropertyChanged отправителем будет элемент. Удалите элемент, если - и только если - свойство, которое может вызвать курорт, было изменено, затем повторно добавьте его (вставьте его в отсортированном положении, если добавление этого еще не делает). Предпочтительнее переместить элемент, если он доступен, а не удалять / добавлять его. Точно так же это нужно делать и с фильтрацией (проверкой предиката фильтра).

IEditableObject не нужен! Если вы хотите отредактировать несколько свойств, затем завершите редактирование (например, отредактируйте 3 свойства, а затем выберите другую строку в WinForm DataGridView), а затем выполните сортировку, это будет правильный способ заставить это работать. Но часто вы, вероятно, захотите, чтобы коллекция обновлялась после изменения каждого свойства без необходимости вручную вызывать BeginEdit / EndEdit. IEditableObject, кстати, присутствует в платформе .NET 2.0 и не является новым для .NET 3.5 (если вы читаете статью доктора).

Примечание. Проблемы могут возникать при использовании BeginEdit () и EndEdit () с несколькими изменениями одного и того же элемента - если вы не увеличиваете (для истины) / не уменьшаете (для false) целое число вместо установки логического значения! Не забудьте увеличивать / уменьшать целое число, чтобы точно знать, когда редактирование закончено.

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

Public Class ListView
  Inherits ListCollectionView

  Protected Overrides Sub OnPropertyChanged(sender As Object, e As PropertyChangedEventArgs)

    ' Add resorting/filtering logic here.
  End Sub
End Class

Лучшим примером коллекции, которая делает то же самое, что вам нужно, является Джесси Джонсонс ObjectListView, хотя он специфичен для .NET 2.0 (IBindingList вместо INotifyCollectionChanged / ObservableCollection / ListCollectionView) и использует очень ограничительную лицензию. Его блог все еще может быть очень ценным в плане того, как он этого добился.

Изменить:

Забыл добавить, что отправитель будет тем элементом, который вам нужно прибегнуть, и e.PropertyName - это то, что вам нужно будет использовать, чтобы определить, входит ли оно в SortDescriptions. В противном случае изменение этого свойства не приведет к необходимости использования курорта. Если e.PropertyName равно Nothing, то это похоже на обновление, при котором многие свойства могли быть изменены, и следует выполнить пересмотр.

Чтобы определить, нужна ли фильтрация, просто пропустите его через FilterPredicate и удалите при необходимости. Фильтрация намного дешевле сортировки.

Надеюсь, полезно,

Тамус-Дж. Ройс

2
ответ дан 3 December 2019 в 20:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: