Comment puis-je avoir un déclencheur WPF EventTrigger sur un View lorsque le Viewmodel sous-jacent le spécifie?
-
07-07-2019 - |
Question
Voici le scénario:
Je dispose du contrôle utilisateur suivant. L’idée est que son modèle de vue devrait pouvoir indiquer à la vue qu’il doit "Activer le rayonnement" et jouer ainsi sur le Storyboard.
<UserControl x:Class="View.UnitView" ... >
...
<Storyboard x:Key="ActivateGlow">
...
</Storyboard>
...
<!-- INVALID BINDING! Not Dependancy Object-->
<EventTrigger RoutedEvent="{Binding OnActivateGlow}">
<BeginStoryboard Storyboard="{StaticResource ActivateGlow}"/>
</EventTrigger>
</UserControl>
dans le code ci-dessous pour UnitView, j'ai:
public event EventHandler ActivateGlow;
et comme c'est assez normal dans MVVM, j'ai le DataTemplate suivant pour UnitViewModel:
<DataTemplate DataType="{x:Type vm:UnitViewModel}">
<vw:UnitView d:DesignWidth="150" d:DesignHeight="100" />
</DataTemplate>
La question ultime est de savoir comment configurer quelque chose pour que le modèle de vue puisse déclencher l'événement OnActivateGlow.
La solution
Mise à jour: Firoso, comme indiqué dans les commentaires, vous devriez pouvoir (je pense - c'est-à-dire non testé) être en mesure d'utiliser les composants du comportement de mélange pour répondre à vos besoins.
En plus du téléchargement et de l’installation du SDK. Obtenez une copie de la bibliothèque d'échantillons de mélange d'expression (vous devez cliquer sur Téléchargements à partir du lien suivant): Exemples d'expression Blend
Cette bibliothèque contient un déclencheur prédéfini appelé 'DataEventTrigger' que vous pouvez utiliser pour déclencher des actions en réponse à un événement déclaré sur votre viewmodel.
Le kit de développement logiciel (SDK) mixte possède déjà (d'après ce que je peux dire) l'autre pièce du puzzle: il inclut déjà une action permettant de contrôler les story-boards. Le nom de cette action est 'ControlStoryboardAction'.
Vous devriez vous retrouver avec un xaml qui ressemble à ceci:
<i:Interaction.Triggers>
<samples:DataEventTrigger EventName="YourEvent">
<im:ControlStoryboardAction Storyboard="{StaticResource Storyboard1}"
ControlStoryboardOption="Play"/>
</samples:DataEventTrigger>
</i:Interaction.Triggers>
Remplacez 'YourEvent' par le nom de l'événement que vous avez défini sur votre modèle de vue, et remplacez 'Storyboard1' par le nom de votre storyboard. Bien sûr, les noms devront correspondre exactement.
Voici les définitions d'espace de noms xaml utilisées:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:im="clr-namespace:Microsoft.Expression.Interactivity.Media;assembly=Microsoft.Expression.Interactions"
xmlns:samples="clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity"
Message original, avant modification:
Vous suggère de vous pencher sur les comportements Expression Blend:
Autres conseils
Vous pouvez également placer une propriété booléenne IsGlowing sur votre modèle de vue et utiliser des déclencheurs de données dans votre style
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsGlowing}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
...
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
Je pense que vous devez vous connecter à un RoutedEvent
, pas un événement CLR.
Je n'ai pas essayé, mais quelque chose comme ça devrait marcher:
public class UnitView
{
public static readonly RoutedEvent ActivateGlowEvent
= EventManager.RegisterRoutedEvent(
"ActivateGlow", RoutingStrategy.Bubble,
typeof(RoutedEventHandler), typeof(UnitView)
);
public void RaiseActivateGlowEvent()
{
RaiseEvent(new RoutedEventArgs(ActivateGlowEvent));
}
}
Une des solutions que j’ai trouvée pour résoudre ce problème consiste à utiliser un déclencheur de données sur un DataTemplate contenant le contrôle ci-dessus ... Ce n’est probablement pas la meilleure façon de procéder. Je suis toujours ouvert aux meilleures idées.