Эффективность работы WPF DataGrid

Я тестирую WPF DataGrid в надежде заменить некоторые элементы управления winforms, и до сих пор был очень доволен процессом разработки. Производительность, похоже, сейчас самая большая проблема. Моя рабочая станция разработки имеет почти лучшие процессоры на рынке, работающие под управлением Windows 7, с 6 гигабайтами памяти DDR3. Управление окнами, которые я заменяю, значительно более чувствительно, что вызывает беспокойство.

Мой тест - это базовая реализация DataGrid, привязанная к ObservableCollection, которая обновляется один раз в секунду. Он также включает в себя область сведений, которая расширяема, чтобы показать больше информации о каждой строке. Зона сведений - это только панель стека с помощью TextClock для ItemsControl (которая повторяется 6 раз)

Моя жалоба заключается в том, что, если я пытаюсь прокрутить эту коллекцию, она часто дергается с задержкой, и если я пытаюсь расширить каждую строку по мере ее поступления, около 15% кликов не запускают кнопки click event (DataGridTmplateColumn > CellTemplate > Кнопка DataTemplate > ) Кроме того, прокрутка более неустойчива, если детали некоторых строк расширены (с полосой прокрутки, которая сама по себе изменяет ее размеры по мере продвижения вверх/вниз).

какие вещи искать/оптимизировать/избегать?

Обновление

вот несколько моментов, которые я нашел полезными до сих пор:

  • полагайтесь как можно меньше на динамическую компоновку. поскольку каждый компонент содержит много подкомпонентов и в мире динамической компоновки, все они должны вызывать методы измерения и макета, которые могут быть интенсивными. поэтому вместо ширины столбца Auto (или без указанной ширины) используйте фиксированную ширину

  • установите WPF Performance Suite и свяжитесь с тем, как ваше приложение отображается. trully awesome app

  • как указал Андрей, ListView - отличная альтернатива, поскольку вам не нужны расширенные функции DataGrid, такие как обновление данных или возможно просмотр деталей (которые я все еще надеюсь воспроизвести)

  • также SuspendableObservableCollection идеально подходит, когда вы добавляете несколько элементов за очень короткий промежуток времени (т.е. 100 пунктов в 0,01 секунды и т.д.)

  • после множества тестов я обнаружил, что BindingList намного быстрее, чем ObservableCollection. Я опубликовал снимки профайлера профилей здесь той же нагрузки, которую обрабатывает коллекция BindingList vs Observable, а первая занимает менее половины процессорного времени. (имейте в виду, что это не только производительность коллекции, но и в сочетании с ListView)

мой поиск по-прежнему продолжается, поскольку что-то кажется утечкой памяти в моем приложении и замедляет ее до остановки через пару часов.

Ответы

Ответ 1

Вы имеете в виду DataGrid из WPF Toolkit? Если да, по-моему, это довольно медленно, поэтому я закончил использование ListView с GridView.

Ответ 2

Общий совет для проблем производительности DataGrid: у меня была проблема с DataGrid, в которой потребовалось буквально секунд, чтобы обновить после изменения размера окна, сортировки столбцов и т.д. и заблокировал пользовательский интерфейс окна, когда он это делал (1000 строк, 5 столбцов).

Это привело к проблеме (ошибка?) с расчетами размера WPF. Я имел это в сетке с RowDefinition Height = "Auto", которая заставляла систему рендеринга попробовать и пересчитать размер DataGrid во время выполнения, измеряя размер каждого столбца и строки, предположительно, заполнив всю сетку ( как я понимаю). Он должен воспринимать это разумно каким-то образом, но в этом случае это не так.

Быстрая проверка, чтобы убедиться, что это связанная с этим проблема, заключается в том, чтобы установить значения высоты и ширины DataGrid на фиксированный размер в течение всего теста и повторить попытку. Если ваша производительность восстановлена, среди этих опций может быть постоянное исправление:

  • Измените размеры содержащихся элементов как относительные (*) или фиксированные значения
  • Установите MaxHeight и MaxWidth DataGrid на фиксированное значение больше чем он может нормально работать.
  • Попробуйте использовать другой тип контейнера с другой стратегией изменения размера (Grid, DockPanel и т.д.).

Ответ 3

Дополнительные советы:

Для прокрутки мы сделали попытку использовать прокрутку с отсрочкой.

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

Для сеток с большим количеством столбцов применяется также ColumnVirtualization. Это имеет тенденцию влиять на горизонтальную прокрутку немного неблагоприятно, но вы можете проверить свой сценарий и применить улучшения. Для нас это работало отлично. Это помогло нам в сценариях Refresh, Reload, Render для больших сеток.

Производительность также зависит от применяемого стиля.