2011-02-03 1 views
1

Comment connecter des propriétés de contrôle personnalisées en cours d'animation dans un modèle de contrôle?Utilisation d'une propriété de contrôle personnalisée dans une animation

Je crée un bouton personnalisé avec plusieurs états et je souhaite animer la couleur du texte du bouton lorsque l'état change. Normalement, le texte est gris et il devient noir sur un MouseOver.

J'ai créé un NormalTextBrush pour le texte noir, et un FadedTextBrush pour le texte gris:

<SolidColorBrush x:Key="NormalTextBrush" Color="Black" /> 
<SolidColorBrush x:Key="FadedTextBrush" Color="DarkSlateGray" /> 

Jusqu'à présent, si bon. Mes animations s'exécutent sans erreur. Lorsque la souris passe sur le bouton, le texte passe du gris au noir. Mais ce que je veux vraiment faire c'est laisser un développeur utilisant le contrôle spécifier la couleur du texte. Par conséquent, je redéfinis les deux styles de texte en tant que liaisons à la propriété Premier plan du contrôle. Le FadedTextBrush utilise un convertisseur de valeur pour fondre la couleur de premier plan. Les ressources redéfinies ressemblent à ceci:

<SolidColorBrush x:Key="NormalTextBrush" Color="{Binding Path=Foreground, RelativeSource={RelativeSource TemplatedParent}}" /> 
<SolidColorBrush x:Key="FadedTextBrush" Color="{Binding Path=Foreground, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ColorConverter}, ConverterParameter='1.2'}" /> 

Et c'est là que j'ai des problèmes. WPF n'autorise pas les liaisons sur les animations dans les modèles de contrôle. Il déclenche une exception avec le message "Impossible de geler l'arborescence du scénario Storyboard pour une utilisation sur plusieurs threads". Le problème est documenté here. Et cela m'amène à ma question: comment configurer mes ressources Brush pour qu'elles soient connectées à la propriété Foreground, mais pour pouvoir les utiliser avec les animations de mon modèle de contrôle?

Quiconque peut répondre à celui-ci, je vais vous acheter une bière la prochaine fois que je vous vois! Merci de votre aide.

Répondre

0

Vous devez faire avec les outils à votre disposition. Je suggère deux blocs de texte qui occupent le même espace d'écran, puis manipuler l'opacité de chacun dans un storyboard. Voici comment superposer deux blocs de texte où le haut est transparent dans l'état par défaut:

<Grid> 
    <TextBlock x:Name="textBlock1" Foreground="Black" 
     Margin="{TemplateBinding Padding}" 
     VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
     HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
     SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
     Text="{TemplateBinding Content}"/> 
    <TextBlock x:Name="textBlock2" Foreground="Gray" 
     Margin="{TemplateBinding Padding}" 
     VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
     HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
     SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
     Text="{TemplateBinding Content}" Opacity="0"/> 
</Grid> 

ensuite mis en place un groupe d'état visuel avec le gestionnaire de l'état visuel d'échanger leurs opacités:

<VisualStateGroup x:Name="CommonStates"> 
    <VisualStateGroup.Transitions> 
     <VisualTransition GeneratedDuration="0:0:0.5"/> 
    </VisualStateGroup.Transitions> 
    <VisualState x:Name="Normal"/> 
    <VisualState x:Name="MouseOver"> 
     <Storyboard> 
      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="textBlock1"> 
       <EasingDoubleKeyFrame KeyTime="0" Value="0"/> 
      </DoubleAnimationUsingKeyFrames> 
      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="textBlock2"> 
       <EasingDoubleKeyFrame KeyTime="0" Value="1"/> 
      </DoubleAnimationUsingKeyFrames> 
     </Storyboard> 
    </VisualState> 
    <VisualState x:Name="Pressed"/> 
    <VisualState x:Name="Disabled"/> 
</VisualStateGroup> 

ou vous pouvez utiliser vos propres storyboards. Le fait est que nous manipulons maintenant des valeurs constantes avec le storyboard et pourtant vous pouvez définir le premier plan du bloc de texte de chaque état en utilisant n'importe quelle méthode de votre choix.

+0

J'ai accepté cette réponse, car elle répond à la question telle que je l'ai posée. Mais je pense qu'il y a une solution plus simple - je vais vider l'animation de changement d'état et effectuer des changements d'état à l'aide de déclencheurs de style. –

Questions connexes