Оптимизация производительности: элементы управления

Windows Presentation Foundation включает множество общих компонентов пользовательского интерфейса (UI), которые используются в большинстве приложений Windows. В этом разделе описываются методы повышения производительности пользовательского интерфейса.

Отображение больших наборов данных

Элементы управления WPF, такие как ListView и ComboBox, используются для отображения списков элементов в приложении. Если отображаемый список большой, это может повлиять на производительность приложения. Причина этого в том, что стандартная система макета создает контейнер макета для каждого элемента, связанного с элементом управления «Список», и вычисляет размер и положение его макета. Как правило, не требуется отображать все элементы одновременно; можно отображать подмножество элементов, и пользователь будет прокручивать список. В этом случае имеет смысл использовать виртуализацию пользовательского интерфейса, что означает, что создание контейнера элемента и вычисление связанной разметки для элемента откладывается до тех пор, пока этот элемент не станет видимым.

Виртуализация пользовательского интерфейса является важным аспектом элементов управления «Список». Не следует путать виртуализацию пользовательского интерфейса с виртуализацией данных. Виртуализация пользовательского интерфейса хранит в памяти только видимые элементы, но в сценариях привязки данных хранит в памяти всю структуру данных. В отличие от этого виртуализация данных хранит в памяти только элементы данных, которые отображаются.

По умолчанию виртуализация пользовательского интерфейса включена для элементов управления ListView и ListBox, если их элементы в списке связаны с данными. Виртуализацию TreeView можно включить, задав для подключенного свойства VirtualizingStackPanel.IsVirtualizing значение true. Чтобы включить виртуализацию пользовательского интерфейса для настраиваемых элементов управления, созданных на основе ItemsControl или существующих элементов управления, использующих класс StackPanel, например, ComboBox, можно задать для ItemsPanel значение VirtualizingStackPanel, а для IsVirtualizing значение true. К сожалению, вы можете отключить виртуализацию пользовательского интерфейса для этих элементов управления, не осознавая этого. Ниже приведен список условий, отключающих виртуализацию пользовательского интерфейса.

  • Контейнеры элементов добавляются непосредственно в ItemsControl. Например, если приложение явным образом добавляет объекты ListBoxItem в ListBox, ListBox не виртуализирует объекты ListBoxItem.

  • Контейнеры элементов в ItemsControl относятся к различным типам. Например, объект Menu, использующий объекты Separator, не может применить повторное использование элементов, так как Menu содержит объекты типа Separator и MenuItem.

  • Настройка для CanContentScroll значения false.

  • Настройка для IsVirtualizing значения false.

Важным аспектом при виртуализации контейнеров элементов является наличие информации о дополнительном состоянии, связанной с контейнером элемента, принадлежащим этому элементу. В этом случае необходимо сохранить это дополнительное состояние. Например, у вас может быть элемент, который содержится в элементе управления Expander, а состояние IsExpanded связано с контейнером элемента, а не с самим элементом. Если контейнер повторно используется для нового элемента, текущее значение IsExpanded используется для нового элемента. Кроме того, старый элемент теряет правильное значение IsExpanded.

В настоящее время элементы управления WPF не предоставляют встроенную поддержку виртуализации данных.

Повторное использование контейнера

Оптимизация виртуализации пользовательского интерфейса, добавленная в .NET Framework 3.5 SP1 для элементов управления, которые наследуют от ItemsControl, заключается в повторном использовании контейнера, что также может повысить быстродействие прокрутки. Когда ItemsControl, использующий виртуализацию пользовательского интерфейса, заполняется, он создает контейнер для каждого элемента, который попадает в представление, и уничтожает контейнеры для всех элементов, которые не попадают в представление. Повторное использование контейнера позволяет элементу управления повторно использовать существующие контейнеры элементов для других элементов данных, так что контейнеры элементов не нужно постоянно создавать и удалять по мере прокрутки пользователем элемента ItemsControl. Можно включить повторное использование элемента, задав подключенное свойство VirtualizationMode со значением Recycling.

Все ItemsControl, которые поддерживают виртуализацию, поддерживают повторное использование контейнеров. Пример того, как включить повторное использование контейнера в ListBox, см. в разделе Улучшение производительности прокрутки ListBox.

Поддержка двунаправленной виртуализации

VirtualizingStackPanel предлагает встроенную поддержку виртуализации пользовательского интерфейса в одном направлении, горизонтально или вертикально. Если вы хотите использовать для своих элементов управления двунаправленную виртуализацию, необходимо реализовать пользовательскую панель, расширяющую класс VirtualizingStackPanel. Класс VirtualizingStackPanel предоставляет виртуальные методы, такие как OnViewportSizeChanged, LineUp, PageUp и MouseWheelUp. Эти виртуальные методы позволяют обнаруживать изменения в видимой части списка и обрабатывать их соответствующим образом.

Оптимизация шаблонов

Визуальное дерево содержит все визуальные элементы приложения. В дополнение к непосредственно созданным объектам оно также содержит объекты, возникшие из-за расширения шаблона. Например, когда вы создаете Button, вы также получаете объекты ClassicBorderDecorator и ContentPresenter в визуальном дереве. Без оптимизации шаблонов элементов управления может быть создано большое число дополнительных ненужных объектов в визуальном дереве. Дополнительные сведения см. в разделе Общие сведения об отрисовке графики в WPF.

Отложенная прокрутка

По умолчанию, когда пользователь перетаскивает бегунок в полосе прокрутки, представление содержимого постоянно обновляется. Если скорость прокрутки в элементе управления низкая, рассмотрите возможность использования отложенной прокрутки. При отложенной прокрутке содержимое обновляется только в том случае, когда пользователь отпускает бегунок.

Чтобы применить отложенный скроллинг, настройте для свойства IsDeferredScrollingEnabled значение true. IsDeferredScrollingEnabled является подключенным свойством, и его можно задать в ScrollViewer и в любом элементе управления, в шаблоне элемента управления которого содержится ScrollViewer.

Элементы управления, реализующие функции производительности

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

Элемент управления Виртуализация Повторное использование контейнера Отложенная прокрутка
ComboBox Можно включить Можно включить Можно включить
ContextMenu Можно включить Можно включить Можно включить
DocumentViewer Недоступно Недоступно Можно включить
ListBox По умолчанию Можно включить Можно включить
ListView По умолчанию Можно включить Можно включить
TreeView Можно включить Можно включить Можно включить
ToolBar Недоступно Недоступно Можно включить

Примечание.

Пример того, как включить виртуализацию и повторное использование контейнера в TreeView, см. в разделе Улучшение производительности TreeView.

См. также