Share via


Aplicar estilo a los controles al recibir el foco y FocusVisualStyle

Windows Presentation Foundation (WPF) proporciona dos mecanismos paralelos para cambiar el aspecto visual de un control cuando recibe el foco de teclado. El primer mecanismo consiste en usar establecedores de propiedad para propiedades como IsKeyboardFocused dentro del estilo o la plantilla que se aplica al control. El segundo mecanismo consiste en proporcionar un estilo independiente como valor de la propiedad FocusVisualStyle; el "estilo visual de foco" crea un árbol visual independiente para un adorno que dibuja encima del control, en lugar de cambiar el árbol visual del mismo u otro elemento de la interfaz de usuario reemplazándolo. En este tema se describen los escenarios en los que es apropiado cada uno de estos mecanismos.

La finalidad del estilo visual de foco

La característica de estilo visual de foco proporciona un "modelo de objetos" común para especificar información visual al usuario basándose en la navegación mediante el teclado a cualquier elemento de la interfaz de usuario. Esto es posible sin aplicar una nueva plantilla al control ni conocer la composición de la plantilla concreta.

Pero, y precisamente porque la característica de estilo visual de foco funciona sin conocer las plantillas de control, la información visual que se puede mostrar para un control usando un estilo visual de foco es necesariamente limitada. Lo que la característica hace en realidad es superponer un árbol visual diferente (un adorno) sobre el árbol visual creado por la representación de un control a través de su plantilla. Este árbol visual independiente se define mediante un estilo que rellena la propiedad FocusVisualStyle.

Comportamiento predeterminado del estilo visual de foco

Los estilos visuales de foco solo actúan cuando la acción de foco se inicia desde el teclado. Los cambios de foco provocados por acciones del mouse o mediante programación deshabilitan el modo de estilos visuales de foco. Para más información sobre las distinciones entre los modos de foco, vea Información general sobre el foco.

Los temas para los controles incluyen un comportamiento de estilo visual de foco predeterminado que pasa a ser el estilo visual de foco para todos los controles del tema. Este estilo de tema se identifica mediante el valor de la clave estática FocusVisualStyleKey. Al declarar su propio estilo visual de foco en el nivel de aplicación, se reemplaza este comportamiento de estilo predeterminado de los temas. Como alternativa, si define el tema completo, entonces deberá usar esta misma clave para definir el estilo correspondiente al comportamiento predeterminado para todo el tema.

En los temas, el estilo visual de foco predeterminado suele ser muy simple. A continuación se muestra una aproximación sin detallar:

<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>

Cuándo usar estilos visuales de foco

Conceptualmente, el aspecto de los estilos visuales de foco aplicados a los controles debe ser coherente para todos los controles. Una manera de asegurar la coherencia es cambiar el estilo visual de foco únicamente si se está creando un tema completo, donde cada control que se defina obtendrá exactamente el mismo estilo visual de foco, o bien una variación de un estilo que guarde una relación visual en todos los controles. Como alternativa, se puede usar el mismo estilo (o estilos similares) para aplicárselos a todos los elementos que pueden recibir el foco del teclado de una página o una interfaz de usuario.

Los estilos visuales de foco no están pensados para establecer la propiedad FocusVisualStyle de estilos de controles individuales que no forman parte de un tema. Esto se debe a que un comportamiento visual incoherente en los distintos controles puede dar lugar a una experiencia del usuario confusa con respecto al foco de teclado. Si quiere controlar comportamientos específicos del control en cuanto al foco de teclado que no son coherentes de manera deliberada para todo el tema, un enfoque mucho mejor consiste en usar desencadenadores en estilos para propiedades de estados de entrada individuales, como IsFocused o IsKeyboardFocused.

Los estilos visuales de foco actúan exclusivamente para el foco de teclado. Como tales, los estilos visuales de foco son un tipo de característica de accesibilidad. Si quiere efectuar cambios en la interfaz de usuario para cualquier tipo de foco, ya sea mediante el mouse, el teclado o programación, no debe usar los estilos visuales de foco sino establecedores y desencadenadores de estilos o plantillas que funcionen partiendo del valor de las propiedades de foco generales, IsFocused o IsKeyboardFocusWithin.

Cómo crear un estilo visual de foco

El estilo que cree para un estilo visual de foco siempre debe tener TargetType de Control. El estilo debe esta compuesto principalmente de un objeto ControlTemplate. No se especifica el tipo de destino de modo que sea el tipo con que se asigna el estilo visual de foco a FocusVisualStyle.

Como el tipo de destino siempre es Control, los estilos se deben aplicar mediante propiedades que sean comunes a todos los controles (propiedades de la clase Control y sus clases base). Debe crear una plantilla que funcione correctamente como una superposición a un elemento de la interfaz de usuario y que no oculte áreas funcionales del control. En general, esto significa que la información visual debe aparecer fuera de los márgenes del control, o en forma de efectos temporales o discretos que no bloqueen las pruebas de posicionamiento del control al que se aplica el estilo visual de foco. Entre las propiedades que puede usar en el enlace a plantilla que son útiles para determinar el dimensionamiento y el posicionamiento de la plantilla de superposición se incluyen ActualHeight, ActualWidth, Margin y Padding.

Alternativas al uso de un estilo visual de foco

En aquellas situaciones en que no sea apropiado usar un estilo visual de foco, ya sea porque el estilo se aplica a controles individuales o porque se quiere un mayor control sobre la plantilla de control, existen muchas otras propiedades y técnicas accesibles capaces de crear comportamiento visual en respuesta a los cambios de foco.

Los desencadenadores, establecedores y establecedores de eventos se describen con detalle en Aplicar estilos y plantillas. El control de eventos enrutados se describe en Información general sobre eventos enrutados.

IsKeyboardFocused

Si le interesa el foco de teclado en concreto, se puede usar la propiedad de dependencia IsKeyboardFocused para una propiedad Trigger. Un desencadenador de propiedad de un estilo o plantilla constituye una técnica más adecuada para definir el comportamiento de foco de teclado más específico para un único control y que no coincida visualmente con el comportamiento de foco de teclado de los demás controles.

Otra propiedad de dependencia similar es IsKeyboardFocusWithin, que podría resultar adecuada si se quiere destacar visualmente que el foco de teclado se encuentra en algún punto de una composición o dentro del área funcional del control. Por ejemplo, es posible colocar un desencadenador de IsKeyboardFocusWithin para que un panel que agrupe varios controles aparezca de otra forma, aunque el foco de teclado se encuentre, en concreto, en uno de los elementos individuales de ese panel.

También puede usar los eventos GotKeyboardFocus y LostKeyboardFocus (así como sus equivalentes de versión preliminar). Puede usar estos eventos como base de un objeto EventSetter, o bien puede escribir controladores para los eventos en el código subyacente.

Otras propiedades de foco

Si quiere que todas las causas posibles del cambio de foco generen un comportamiento visual, debe basar un establecedor o desencadenador en la propiedad de dependencia IsFocused, o bien en los eventos GotFocus o LostFocus que se usan para un objeto EventSetter.

Consulte también