Question

Ceci est une situation qui revient souvent:

Dans la vue, vous avez un contrôle lié à une propriété ViewModel (soutenu par un INotifyPropertyChanged). Par exemple:

<TextBlock Text="{Binding Path=Subtotal}"/>

Lorsque les changements de propriété, vous devez attirer l'attention de l'utilisateur sur le fait avec une animation créative. Comment puis-je utiliser le fait que la vue est déjà câblé à la notification et éviter de créer une grande partie du code supplémentaire (ou au moins créer une fois et la réutilisation). déclencheurs de données sont probablement le meilleur choix, mais je ne sais pas comment les faire feu sur tout changement de valeur par rapport à une valeur spécifique.

Les options suivantes viennent à l'esprit:

  • déclencher un événement supplémentaire dans le ViewModel, abonnez-vous dans la vue code-behind.
  • créer une DataTrigger liée à la propriété en utilisant un convertisseur mentionnés qui retourne vrai si la valeur change.
  • créer un DataTrigger lié à une nouvelle propriété booléenne sur le ViewModel qui est utilisé pour « signal » le changement.
  • créer un comportement attaché au contrôle qui souscrirait au changement de propriété de dépendance et démarrer l'animation du contrôle.

Lequel préférez-vous / utiliser? Ai-je raté toutes les options?

P.S. Ce serait bien (mais pas critique) si la solution offrirait une possibilité de démarrer l'animation d'abord et refléter le changement de valeur quand il est terminé.

Était-ce utile?

La solution

Ok, voilà ce que je suis venu après quelques expériences.

Je l'ai créé une Expression Blend 3 déclencheur avec une propriété de dépendance (je l'ai appelé abonnement). Je lie l'abonnement à la même valeur que mon TextBlock est lié à ce déclencheur est attaché à un ControlStoryboardAction d'Expression Blend 3.

Voici le déclencheur:

public class DataTriggerPlus : TriggerBase<DependencyObject>
{
    public static readonly DependencyProperty SubscriptionProperty =
        DependencyProperty.Register("Subscription", 
            typeof(string),
            typeof(DataTriggerPlus),
            new FrameworkPropertyMetadata("",
              new PropertyChangedCallback(OnSubscriptionChanged)));

    public string Subscription
    {
        get { return (string)GetValue(SubscriptionProperty); }
        set { SetValue(SubscriptionProperty, value); }
    }

    private static void OnSubscriptionChanged(DependencyObject d,
      DependencyPropertyChangedEventArgs e)
    {
        ((DataTriggerPlus)d).InvokeActions(null);
    }
}

Voici comment il est attaché à la table de montage:

<TextBlock x:Name="textBlock" Text="{Binding TestProp}" Background="White">
    <i:Interaction.Triggers>
        <local:DataTriggerPlus Subscription="{Binding TestProp}">
            <im:ControlStoryboardAction 
                Storyboard="{StaticResource Storyboard1}"/>
        </local:DataTriggerPlus>
    </i:Interaction.Triggers>
</TextBlock>

J'aime cette approche beaucoup, excellent travail Blend 3 designers!

Edit: Drew ... répondre à un commentaire

Oui, il est livré avec Blend. Vous pouvez simplement inclure Microsoft.Expression.Interactions.dll et System.Windows.Interactivity dans votre projet.

Et oui, il est bavard (j'ai demandé si quelqu'un a trouvé un bon moyen d'appliquer des comportements via Styles dans cette question ) - mais il y a aussi un avantage de flexibilité. Par exemple, vous pouvez non seulement lancer un story-board, mais aussi passer un état ou faire une autre action du même déclencheur.

Autres conseils

Vous pouvez créer un déclencheur qui va commencer l'animation.

Quelque chose comme ceci:

<Style>
    <Style.Triggers>
       <Trigger 
            Property="ViewModelProperty"
            Value="True">
            <Trigger.EnterActions>
                 <BeginStoryboard Storyboard="YourStoryBoard" />
            </Trigger.EnterActions>
       </Trigger>
    </Style.Triggers>
</Style>

En ce qui concerne la question de la question de la définition de la valeur une fois l'animation terminée, c'est un peu d'une douleur. Pour autant que je suis conscient que vous auriez besoin d'utiliser l'événement terminé sur le story-board, cela nécessite un code derrière, ce qui est quelque chose que vous voulez éviter avec MVVM.

Je l'ai essayé d'utiliser eventtriggers de se lier aux événements terminés, mais présente également quelques complications. Voir pour plus de détails.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top