2010-09-05 5 views
8

J'ai une application WPF, et j'essaye de styler un TextBox en utilisant le Gestionnaire d'état visuel .Net v4. Plus précisément, j'essaie de définir les couleurs du premier plan et de l'arrière-plan pour l'état MouseOver.Problème au premier plan avec Visual State Manager

Ce qui se passe est que, bien que l'arrière-plan et la bordure changent parfaitement, le premier plan ne l'est pas. Si les pinceaux que j'utilise obtiennent leur couleur via une StaticResource, le premier plan ne change pas du tout. Si les pinceaux que j'utilise obtiennent leur couleur via DynamicResource, lorsque je survole un TextBox, le premier plan de toutes les boîtes de texte change. Clairement, soit je fais quelque chose de mal, soit ce que je veux faire n'est tout simplement pas possible avec VSM (ce qui serait plutôt décevant).

Voici les ressources que j'utilise:

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

Il me est très étrange que les brosses de fond et boarder, qui sont créés et animés exactement de la même façon, fonctionnent parfaitement indépendamment du fait que je utilisez des ressources statiques ou dynamiques, mais pas la couleur de premier plan.

Si quelqu'un a des idées, ou s'il y a une meilleure façon de le faire, j'aimerais l'entendre.

David Mullin IMA Technologies

Répondre

15

Les VisualStateManager propriétés ne peuvent pas contrôler dont les valeurs sont fixées par une liaison. Dans votre exemple, Background et BorderBrush sont définis sur des valeurs locales (Transparent) et par conséquent le VSM peut les animer. D'autre part, Foreground est défini à l'aide d'un TemplateBinding et le VSM ne pourra donc pas l'animer si une valeur de liaison est en vigueur.

Ceci est une limitation générale du VisualStateManager et vous le verrez dans tous les exemples où il est utilisé. Une stratégie typique pour contourner le problème consiste à utiliser des calques et de l'opacité pour donner l'illusion d'une animation de couleur alors que ce qui se passe réellement est un fondu d'un élément à un autre. Cela fonctionne parce que vous avez un contrôle total sur le calque caché et n'avez pas besoin de le lier à quoi que ce soit. Malheureusement, cela ne fonctionnera pas pour vos besoins, car l'élément n'est pas statique; vous ne pouvez pas avoir deux zones de texte. L'effet net est que je ne pense pas que vous pouvez à la fois animer la couleur de premier plan du texte et permettre à l'utilisateur de spécifier la couleur de premier plan.

Questions connexes