2010-09-05 13 views
8

Tengo una aplicación WPF y estoy intentando diseñar un TextBox utilizando .Net v4 Visual State Manager. Específicamente, estoy intentando establecer los colores del primer plano y el fondo para el estado de MouseOver.Configuración del problema Primer plano con Visual State Manager

Lo que está sucediendo es que, mientras que el fondo y el borde cambian perfectamente, el primer plano no lo es. Si los pinceles que estoy utilizando obtienen su color a través de un StaticResource, entonces el primer plano no cambia en absoluto. Si los pinceles que uso obtienen su color a través de DynamicResource, cuando muevo el mouse sobre un TextBox, el primer plano de todos los cuadros de texto cambia. Claramente, o estoy haciendo algo mal, o lo que quiero hacer simplemente no es posible con VSM (lo que sería bastante decepcionante).

Éstos son los recursos que estoy usando:

<Color x:Key="ControlBackgroundColor" R="178" G="178" B="178" A="255" /> 
<Color x:Key="ControlForegroundColor" R="0" G="0" B="0" A="255" /> 
<Color x:Key="BorderColor" R="127" G="127" B="127" A="255" /> 
<Color x:Key="MouseOverControlBackgroundColor" R="0" G="0" B="0" A="255" /> 
<Color x:Key="MouseOverControlForegroundColor" R="255" G="255" B="255" A="255" /> 
<Color x:Key="MouseOverBorderColor" R="178" G="178" B="178" A="255" /> 

<SolidColorBrush PresentationOptions:Freeze="True" x:Key="ControlBackgroundBrush" Color="{DynamicResource ControlBackgroundColor}" /> 
<SolidColorBrush PresentationOptions:Freeze="True" x:Key="ControlForegroundBrush" Color="{DynamicResource ControlForegroundColor}" /> 
<SolidColorBrush PresentationOptions:Freeze="True" x:Key="BorderBrush" Color="{DynamicResource BorderColor}" /> 

<SolidColorBrush PresentationOptions:Freeze="True" x:Key="MouseOverControlBackgroundBrush" Color="{DynamicResource MouseOverControlBackgroundColor}" /> 
<SolidColorBrush PresentationOptions:Freeze="True" x:Key="MouseOverControlForegroundBrush" Color="{DynamicResource MouseOverControlForegroundColor}" /> 
<SolidColorBrush PresentationOptions:Freeze="True" x:Key="MouseOverBorderBrush" Color="{DynamicResource MouseOverBorderColor}" /> 

<Style TargetType="{x:Type TextBox}" > 
    <Setter Property="BorderThickness" Value="1"/> 
    <Setter Property="Padding" Value="2"/> 
    <Setter Property="Margin" Value="1" /> 
    <Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}" /> 
    <Setter Property="Background" Value="{DynamicResource ControlBackgroundBrush}" /> 
    <Setter Property="Foreground" Value="{DynamicResource ControlForegroundBrush}" /> 

    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="TextBox"> 
       <Grid x:Name="RootElement"> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="CommonStates"> 
          <VisualState x:Name="Normal"/> 
          <VisualState x:Name="MouseOver"> 
           <Storyboard> 
            <ColorAnimation Storyboard.TargetName="MouseOverBorder" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" To="{DynamicResource MouseOverBorderColor}" Duration="0:0:0.3"/> 
            <ColorAnimation Storyboard.TargetName="MouseOverBorder" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="{DynamicResource MouseOverControlBackgroundColor}" Duration="0:0:0.3"/> 
            <ColorAnimation Storyboard.TargetName="PART_ContentHost" Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)" To="{DynamicResource MouseOverControlForegroundColor}" Duration="0:0:0.3"/> 
           </Storyboard> 
          </VisualState> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 
        <Border x:Name="Border" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1" Opacity="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"> 
         <Grid x:Name="ContentGrid"> 
          <Border x:Name="MouseOverBorder" BorderThickness="1" BorderBrush="Transparent" Background="Transparent"> 
           <ScrollViewer x:Name="PART_ContentHost" Padding="{TemplateBinding Padding}" Foreground="{TemplateBinding Foreground}" BorderThickness="0" IsTabStop="False"/> 
          </Border> 
         </Grid> 
        </Border> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Es muy extraño para mí que el fondo y al huésped cepillos, los cuales son creados y animados exactamente de la misma manera, funcionan perfectamente sin importar si yo utilice recursos estáticos o dinámicos, pero el color de primer plano no.

Si alguien tiene alguna idea, o si hay una mejor manera de hacerlo, me encantaría escucharla.

David Mullin IMA Tecnologías

Respuesta

15

Los VisualStateManager no pueden controlar las propiedades cuyos valores se establecen a través de una unión. En su ejemplo, tanto Background como BorderBrush se establecen en valores locales (Transparent) y, por lo tanto, VSM puede animarlos. Por otro lado, Foreground se establece utilizando un TemplateBinding y, por lo tanto, el VSM no podrá animarlo si un valor de enlace está en vigor.

Esta es una limitación general del VisualStateManager y lo verá en todos los ejemplos donde se usa. Una estrategia típica para evitar el problema es utilizar capas y opacidad para dar la ilusión de animación en color cuando realmente lo que sucede es un fundido de un elemento a otro. Esto funciona porque tienes control total sobre la capa oculta y no tienes que vincularla a nada. Lamentablemente, esto no funcionará para sus necesidades porque el elemento no es estático; no puedes tener dos cuadros de texto.

El efecto neto es que no creo que pueda animar el color de primer plano del texto y permitir que el color de primer plano sea especificado por el usuario.

Cuestiones relacionadas