Стилизация фокуса в элементах управления и FocusVisualStyle

Windows Presentation Foundation (WPF) предоставляет два параллельных механизма для изменения внешнего вида элемента управления при получении фокуса клавиатуры. Первый механизм — использование методов задания для свойств, таких как IsKeyboardFocused, в стиле или шаблоне, который применяется к элементу управления. Второй механизм представляет собой отдельный стиль в качестве значения свойства FocusVisualStyle. «Визуальный стиль фокуса» создает отдельное визуальное дерево для декоративного элемента, который отображается поверх элемента управления, а не изменяет визуальное дерево элемента управления или другого элемента пользовательского интерфейса путем его замены. В данном разделе рассматриваются сценарии, для которых подходит любой из этих механизмов.

Назначение визуального стиля фокуса

Функция визуального стиля фокуса предоставляет общую "объектную модель" для введения визуальной обратной связи с пользователем на основе навигации с помощью клавиатуры к любому элементу пользовательского интерфейса. Это можно сделать без применения нового шаблона к элементу управления или знания композиции определенного шаблона.

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

Поведение визуального стиля фокуса по умолчанию

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

Темы для элементов управления включают поведение визуального стиля фокуса по умолчанию, который становится визуальным стилем фокуса для всех элементов управления в теме. Этот стиль темы определяется значением статического ключа FocusVisualStyleKey. При объявлении собственного визуального стиля фокуса на уровне приложения можно заменить это поведение стиля по умолчанию из темы. Кроме того, при определении целой темы необходимо использовать этот же ключ для определения стиля поведения по умолчанию для всей темы.

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

<Style x:Key="{x:Static SystemParameters.FocusVisualStyleKey}">
  <Setter Property="Control.Template">
    <Setter.Value>
      <ControlTemplate>
        <Rectangle StrokeThickness="1"
          Stroke="Black"
          StrokeDashArray="1 2"
          SnapsToDevicePixels="true"/>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

Когда следует использовать визуальные стили фокуса

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

Задание FocusVisualStyle для отдельных стилей управления, которые не являются частью темы, не является рекомендуемым использованием визуальных стилей фокуса. Это связано с тем, что несогласованность визуального поведения элементов управления может привести к путанице при использовании фокуса клавиатуры. Если планируется создать конкретное поведение элемента управления для фокуса клавиатуры, которое намеренно не согласовано в рамках темы, гораздо лучше использовать триггеры в стилях для отдельных свойств состояния ввода, таких как IsFocused или IsKeyboardFocused.

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

Создание визуального стиля фокуса

Стиль, создаваемый для визуального стиля фокуса, всегда должен иметь TargetType для Control. Стиль должен состоять в основном из ControlTemplate. Целевой тип как тип, в котором визуальный стиль фокуса назначен для FocusVisualStyle, не указывается.

Так как целевым типом всегда является Control, нужно создать стиль, используя свойства, общие для всех элементов управления (с использованием свойств класса Control и его базовых классов). Необходимо создать шаблон, который будет правильно функционировать как наложение для элемента пользовательского интерфейса и не будет скрывать функциональные области элемента управления. Как правило, это означает, что визуальная обратная связь должна появляться за пределами полей управления или в качестве временных или ненавязчивых эффектов, которые не будут блокировать проверку нажатий в элементе управления, к которому применен визуальный стиль фокуса. Свойствами, которые можно использовать в привязке шаблона, полезные для определения размеров и расположения шаблона наложения, являются ActualHeight, ActualWidth, Margin и Padding.

Альтернативные варианты использования визуального стиля фокуса

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

Триггеры, методы задания и методы задания событий рассматриваются подробно в разделе Использование стилей и шаблонов. Обработка перенаправляемых событий рассматривается в разделе Общие сведения о перенаправляемых событиях.

IsKeyboardFocused

Если вас интересует именно фокус клавиатуры, можно использовать свойство зависимостей IsKeyboardFocused для свойства Trigger. Триггер свойства в стиле или шаблоне является более подходящим методом определения поведения фокуса клавиатуры, который применяется только для отдельного элемента управления и может визуально не соответствовать поведению фокуса клавиатуры других элементов управления.

Другим похожим свойством зависимостей является IsKeyboardFocusWithin, которое можно использовать, если нужно визуально указать, что фокус клавиатуры находится где-то внутри структуры или в функциональной области элемента управления. Например, можно поместить триггер IsKeyboardFocusWithin так, что панель, которая группирует несколько элементов управления, будет выглядеть по-разному, хотя фокус клавиатуры может более точно находиться на отдельном элементе этой панели.

Также можно использовать события GotKeyboardFocus и LostKeyboardFocus (а также их эквиваленты предварительного просмотра). Эти события можно использовать в качестве основы для EventSetter или можно написать обработчики событий в коде программной части.

Другие свойства фокуса

Если требуется, чтобы все возможные причины изменения фокуса порождали визуальное поведение, то следует использовать метод задания или триггер на основе свойства зависимостей IsFocused, либо на основе событий GotFocus или LostFocus, используемых для EventSetter.

См. также