2011-04-14 3 views
5

J'ai un problème avec l'animation couleur. Ceci est ma source:ControlTemplate Problème d'animation couleur du storyboard

<Window.Resources> 
    <hedit:BrushToColorConverter x:Key="BrushToColorConverter" /> 
    <Style x:Key="MyButtonStyle" TargetType="Button"> 
     <Setter Property="OverridesDefaultStyle" Value="True"/> 
     <Setter Property="Margin" Value="5"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="Button"> 
        <ControlTemplate.Resources> 
         <Storyboard x:Key="buttonAnimIn"> 
          <!-- Problem line --> 
          <ColorAnimation Storyboard.TargetName="bntBack" Storyboard.TargetProperty="Color" To="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Converter={StaticResource BrushToColorConverter}}" /> 
         </Storyboard> 
         <Storyboard x:Key="buttonAnimOut"> 
          <ColorAnimation Storyboard.TargetName="bntBack" Storyboard.TargetProperty="Color" To="Blue" /> 
         </Storyboard> 
         <Storyboard x:Key="buttonAnimForegroundIn"> 
          <ColorAnimation Storyboard.TargetName="btnFore" Storyboard.TargetProperty="Color" To="Blue" /> 
         </Storyboard> 
         <Storyboard x:Key="buttonAnimForegroundOut"> 
          <ColorAnimation Storyboard.TargetName="btnFore" Storyboard.TargetProperty="Color" To="Red" /> 
         </Storyboard> 
        </ControlTemplate.Resources> 
        <Border Name="border" 
         BorderThickness="1" 
         Padding="4,2" 
         BorderBrush="DarkGray" 
         CornerRadius="3"> 
         <Border.Background> 
          <SolidColorBrush Color="Blue" x:Name="bntBack" /> 
         </Border.Background> 
         <ContentControl HorizontalAlignment="Center" VerticalAlignment="Center" Content="{TemplateBinding Content}"> 
          <ContentControl.Foreground> 
           <SolidColorBrush Color="Red" x:Name="btnFore" /> 
          </ContentControl.Foreground> 
         </ContentControl > 
        </Border> 
        <ControlTemplate.Triggers> 
         <EventTrigger RoutedEvent="Button.MouseEnter"> 
          <BeginStoryboard Storyboard="{StaticResource buttonAnimIn}" /> 
          <BeginStoryboard Storyboard="{StaticResource buttonAnimForegroundIn}" /> 
         </EventTrigger> 
         <EventTrigger RoutedEvent="Button.MouseLeave"> 
          <BeginStoryboard Storyboard="{StaticResource buttonAnimOut}" /> 
          <BeginStoryboard Storyboard="{StaticResource buttonAnimForegroundOut}" /> 
         </EventTrigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Window.Resources> 

Le problème est:

Impossible de convertir la valeur dans l'attribut 'Style' pour objet de type 'System.Windows.Style'. Impossible de geler l'arborescence de la chronologie de Storyboard pour l'utiliser dans les threads. Erreur à l'objet 'System.Windows.Controls.Button' dans le fichier de marquage 'HLSLEditor; component/mainwindow.xaml' Ligne 223 Position 25.

Lorsque vous utilisiez des couleurs fixes, cela a fonctionné, mais cela ne fonctionne pas avec la couleur de premier plan de la parent ...

Comment faire une animation au premier plan ou à la couleur de fond?

Merci!

+0

Par ailleurs, le point de Storyboards est d'animations de groupe, donc vous normalement avoir un '' InStoryboard' et OutStoryboard', où chacun contient deux animations. –

Répondre

6

Vous ne pouvez pas geler les liaisons, vous pouvez probablement contourner ce problème en déclarant une couleur en tant que ressource, puis en lier l'arrière-plan de votre contrôle à celle-ci tout en utilisant StaticResource dans l'animation.

par exemple.

<Window.Background> 
    <SolidColorBrush Color="{DynamicResource Background}"/> 
</Window.Background> 
<Window.Resources> 
    <Color x:Key="Background">Green</Color> 
</Window.Resources> 
<ColorAnimation Storyboard.TargetProperty="Foreground.Color" 
       Duration="0:0:1" 
       To="{StaticResource Background}"/> 

Alternative en utilisant une classe de ressources:

public static class MyColors 
{ 
    public static Color MyHighlightColor = Color.FromArgb(255, 0, 88, 0); 
} 
<ColorAnimation Storyboard.TargetProperty="Foreground.Color" 
       Duration="0:0:1" 
       To="{x:Static local:MyColors.MyHighlightColor}"/> 
+0

merci pour cette suggestion H.B. Cependant, le problème est que toutes mes couleurs sont dans un fichier de ressources, nous avons skinning dans l'application. existe-t-il un moyen d'aller au-delà de ce qui n'inclut pas les couleurs statiques déclarées dans le fichier xaml? –

+0

Quel type de fichier de ressources? S'il déclare les couleurs comme champs publics statiques, vous pouvez utiliser '{x: Espace de noms statique: Class.Field}' au lieu d'utiliser des ressources statiques. ([x: Référence statique] (http://msdn.microsoft.com/en-us/library/ms742135.aspx)) –

+0

Ajoutée à la réponse. –

2

Je pense que la compréhension de l'erreur peut vous donner un moyen de régler le problème.

L'animation nécessite l'utilisation de threads en plus du thread UI. Les story-boards doivent donc être freezable, ce qui signifie que toutes les animations du storyboard doivent être freezable, et que tout ce que ces animations utilisent doit aussi être freezable.

Les liaisons ne sont pas fractionnables - à peu près par définition, car elles constituent un mécanisme permettant de modifier une propriété de dépendance. Vous ne pouvez pas utiliser une liaison dynamique dans une animation de couleur - il est possible que la propriété change pendant l'exécution de l'animation. La même chose se produit si vous liez un objet ou si vous utilisez DynamicResource. Le fait est que cela vous protège de quelque chose que vous ne voulez vraiment pas de toute façon. Vous ne voulez pas vraiment que les couleurs changent pendant l'exécution de l'animation. Ce n'est pas ce que vous essayez d'accomplir. Vous souhaitez que les ressources de couleur utilisées par l'animation changent si l'utilisateur sélectionne un habillage différent. Ainsi, au lieu de lier les storyboards aux ressources personnalisables, ajoutez les storyboards au dictionnaire des ressources définies lorsque l'habillage change (en utilisant des liaisons statiques pour définir les couleurs) et utilisez la liaison dynamique dans vos déclencheurs d'événement. Cela devrait fonctionner.

+0

Merci pour votre point de vue, c'est malheureusement ce que je pensais après quelques recherches, maintenant avec votre confirmation. XAML out, .cs in semble la seule solution:/ –

+0

Je pense que ce que j'ai suggéré consiste simplement à déplacer XAML, ne pas le remplacer par du code. Je ne sais pas assez sur votre demande pour dire à coup sûr. –

1

Quand je suis tombé sur ce problème, je CONTOURNÉS en modifiant mon style pour contenir deux éléments identiques sur le dessus de l'autre - l'un pour l'état « normal » et un pour l'état « pressé ». Le 'pressé' avait son Opacity mis à 0 par défaut et l'autre avait un Opacity de 1. Mon animation a changé les opacités de 0 à 1 et vice versa.

Cette approche évité animant en fait la propriété Color mais produit le même effet tout en gardant tout en XAML. Comme les couleurs étaient définies dans la définition de style plutôt que dans l'animation, elles pouvaient être liées selon les besoins. Ce ne sera probablement pas adapté à toutes les situations, mais pour mon style assez simple, c'était un moyen très rapide d'obtenir l'effet désiré.

Questions connexes