2010-04-29 8 views
4

J'essaie de créer un effet d'animation simple (je pense) basé sur un changement de propriété dans mon ViewModel. Je voudrais que la cible soit un bloc de texte spécifique dans le modèle de contrôle d'un contrôle personnalisé, qui hérite de Window.WPF: Sélection de la cible d'une animation

À partir des exemples d'articles que j'ai vus, un DataTrigger est le moyen le plus simple d'y parvenir. Il semble que Window.Triggers ne supporte pas DataTriggers, ce qui m'a conduit à essayer d'appliquer le trigger dans le style. Le problème que j'ai actuellement est que je ne peux pas sembler cibler le TextBlock (ou n'importe quel autre contrôle enfant) - ce qui se passe est que le code ci-dessous est que l'animation est appliquée à l'arrière-plan de la fenêtre entière.

Si je ne pars de StoryBoard.Target complètement, l'effet est exactement le même.

Est-ce la bonne approche avec la mauvaise syntaxe, ou existe-t-il un moyen plus facile d'y parvenir?

<Style x:Key="MyWindowStyle" TargetType="{x:Type Window}"> 
    <Setter Property="Template" Value="{StaticResource MyWindowTemplate}"/> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding ChangeOccurred}" Value="True"> 
      <DataTrigger.EnterActions> 
       <BeginStoryboard> 
        <Storyboard BeginTime="00:00:00" Duration="0:0:2" Storyboard.Target="{Binding RelativeSource={RelativeSource AncestorType=TextBlock}}" 
            Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"> 
         <ColorAnimation FillBehavior="Stop" From="Black" To="Red" Duration="0:0:0.5" AutoReverse="True"/> 
        </Storyboard> 
       </BeginStoryboard> 
      </DataTrigger.EnterActions> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

Mise à jour

Il devrait y avoir aussi mentionné que j'ai essayé de nommer le TextBlock et référence via StoryBoard.TargetName (comme suggéré Timores), et obtenu l'erreur « propriété TargetName ne peut pas être sur un Style Setter. "

+0

Quelle est exactement la cible d'animation souhaitée? Vous dites * "un bloc de texte spécifique dans le modèle de contrôle d'un contrôle personnalisé" *, mais créez ensuite un style pour une fenêtre et non un contrôle personnalisé. Pourriez-vous fournir le code contenant votre cible d'animation? La liaison cible ci-dessus ne devrait pas fonctionner car je ne m'attends pas à ce que la fenêtre ait un ancêtre de type TextBlock, n'est-ce pas ?! Est-ce possible? – gehho

+0

Désolé, c'est une configuration difficile à décrire. Le contrôle personnalisé * est * une fenêtre, car elle dérive de la fenêtre. L'installation/le style a été créé par quelqu'un d'autre, alors j'essaie de rééquiper cette animation. Le bloc de texte est un contrôle enfant - en regardant à nouveau ceci, le RelativeSource/AncestorType n'est probablement même pas proche, puisque j'essaye de viser un enfant et pas un parent? –

Répondre

4

EDIT: Je supervisé le fait que le TextBlock est dans la ControlTemplate de votre fenêtre/contrôle personnalisée. Je ne pense pas qu'il est possible de cibler un contrôle au sein l'ControlTemplate d'un Storyboarden dehors de cette ControlTemplate. Vous pouvez cependant définir une propriété sur votre fenêtre personnalisée que vous puisaliez à votre propriété ChangeOccurred, puis ajoutez le déclencheur à votre ControlTemplate qui sera désormais déclenché par la propriété Contrôle personnalisée plutôt que par la propriété ViewModel de la fenêtre (bien sûr, indirectement déclenché par le ViewModel car ChangeOccurred est lié à la propriété de la fenêtre personnalisée qui à son tour déclenche l'animation - euh, phrase complexe, j'espère que vous comprenez). Est-ce une option? Pourriez-vous suivre? ;-)

Peut-être un peu de code aide:

public class MyCustomWindow : Window 
{ 
    public static readonly DependencyProperty ChangeOccurred2 = DependencyProperty.Register(...); 

    public bool ChangeOccurred2 { ... } 

    // ... 
} 

Et certains XAML:

<local:MyCustomWindow ChangeOccurred2="{Binding ChangeOccurred}" ... > 
    <!-- Your content here... --> 
</local:MyCustomWindow> 

<!-- Somewhere else (whereever your ControlTemplate is defined) --> 
<ControlTemplate TargetType="{x:Type local:MyCustomWindow}"> 

    <!-- your template here --> 

    <ControlTemplate.Triggers> 
     <Trigger Property="ChangeOccurred2" Value="True"> 
      <Trigger.EnterActions> 
       <BeginStoryboard> 
        <Storyboard BeginTime="00:00:00" Duration="0:0:2" 
           Storyboard.TargetName="txtWhatever" 
           Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"> 
         <ColorAnimation FillBehavior="Stop" 
             From="Black" To="Red" 
             Duration="0:0:0.5" 
             AutoReverse="True"/> 
        </Storyboard> 
       </BeginStoryboard> 
      </Trigger.EnterActions> 
     </Trigger> 
    </ControlTemplate.Triggers> 
</ControlTemplate> 

Note: Je l'ai appelé la propriété de la fenêtre ChangeOccurred2 parce que je voulais qu'il se distinguer des années ViewModel ChangeOccurred propriété. Bien sûr, vous devriez choisir un meilleur nom pour cette propriété. Cependant, il me manque l'arrière-plan pour une telle décision.


Ma vieille réponse:

Alors, vous voulez animer un TextBlock qui est dans le contenu d'un (personnalisé) Fenêtre ?!

Pourquoi voulez-vous définir le style de la fenêtre, et non pas sur lui-même TextBlock? Peut-être vous devriez essayer quelque chose comme ça (ne pas le tester!):

<local:MyCustomWindow ... > 
    <!-- ... --> 
    <TextBlock x:Name="textBlockAnimated" ... > 
     <TextBlock.Style> 
      <Style TargetType="{x:Type TextBlock}"> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding ChangeOccurred}" Value="True"> 
         <DataTrigger.EnterActions> 
          <BeginStoryboard> 
           <Storyboard BeginTime="00:00:00" Duration="0:0:2" 
              Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"> 
            <ColorAnimation FillBehavior="Stop" 
                From="Black" To="Red" 
                Duration="0:0:0.5" 
                AutoReverse="True"/> 
           </Storyboard> 
          </BeginStoryboard> 
         </DataTrigger.EnterActions> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </TextBlock.Style> 
    </TextBlock> 
    <!-- ... --> 
</local:MyCustomWindow> 

Le {Binding ChangeOccurred} pourrait ne pas être suffisante. Vous devrez peut-être ajouter un DataContext au TextBlock ou ajouter un RelativeSource ou un autre.

+0

Votre réponse mise à jour fonctionne! Merci de votre aide. Je me sentais comme la façon dont je m'approchais était en arrière, mais je suis très nouveau à styliser/animer dans WPF. –

0

Est-ce que le TextBlock est dans le MyWindowTemplate? Si oui, attribuez un nom au TextBlock et utilisez Storyboard.TargetName pour le référencer.

Voir another question in SO

+0

Désolé, je devrais avoir mentionné que j'ai essayé et obtenu: "La propriété TargetName ne peut pas être définie sur un Style Setter." –

+0

Aussi: oui, c'est dans le modèle de contrôle. –