Come posso avere un EventTrigger WPF su un trigger View quando il Viewmodel sottostante lo richiede?
-
07-07-2019 - |
Domanda
Ecco lo scenario:
Ho il seguente controllo utente, l'idea è che il suo modello di vista dovrebbe essere in grado di segnalare alla vista che deve "Attivare il bagliore", quindi giocare allo 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>
nel codebehind di UnitView, ho:
public event EventHandler ActivateGlow;
e come è abbastanza normale in MVVM, ho il seguente DataTemplate per UnitViewModel:
<DataTemplate DataType="{x:Type vm:UnitViewModel}">
<vw:UnitView d:DesignWidth="150" d:DesignHeight="100" />
</DataTemplate>
La domanda ulitmate è: come posso impostare qualcosa in modo che il modello di visualizzazione possa attivare l'evento OnActivateGlow?
Soluzione
Aggiornamento: Firoso, come menzionato nei commenti, dovresti essere in grado (penso - cioè non testato) di essere in grado di utilizzare i componenti del comportamento della fusione per soddisfare le tue esigenze.
Oltre a scaricare e installare l'SDK. Ottieni una copia della libreria degli esempi di blend di espressioni (dovrai fare clic su Download dal seguente link): Esempi di miscele di espressioni
Questa libreria contiene un trigger predefinito chiamato 'DataEventTrigger' che puoi utilizzare per attivare azioni in risposta a un evento dichiarato sul tuo modello di visualizzazione.
L'SDK di fusione ha già (da quello che posso dire) l'altro pezzo del puzzle - include già un'azione che ti consente di controllare gli storyboard. Il nome di questa azione è 'ControlStoryboardAction'.
Dovresti finire con un po 'di xaml che assomiglia a questo:
<i:Interaction.Triggers>
<samples:DataEventTrigger EventName="YourEvent">
<im:ControlStoryboardAction Storyboard="{StaticResource Storyboard1}"
ControlStoryboardOption="Play"/>
</samples:DataEventTrigger>
</i:Interaction.Triggers>
Sostituisci "YourEvent" con il nome dell'evento che hai definito sul tuo modello di visualizzazione e sostituisci "Storyboard1" con il nome dello storyboard. Ovviamente i nomi dovranno corrispondere esattamente.
Ecco le definizioni dello spazio dei nomi xaml utilizzate:
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"
Post originale, prima della modifica:
Suggerisci di esaminare Expression Blend Behaviors:
Altri suggerimenti
Puoi anche mettere una proprietà booleana IsGlowing sul tuo viewmodel e usare datatriggers nel tuo stile
<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>
Credo che dovresti legarti a un
Non l'ho provato, ma qualcosa del genere dovrebbe funzionare:
public class UnitView
{
public static readonly RoutedEvent ActivateGlowEvent
= EventManager.RegisterRoutedEvent(
"ActivateGlow", RoutingStrategy.Bubble,
typeof(RoutedEventHandler), typeof(UnitView)
);
public void RaiseActivateGlowEvent()
{
RaiseEvent(new RoutedEventArgs(ActivateGlowEvent));
}
}
Un modo in cui ho scoperto di risolverlo è utilizzare un trigger di dati su un DataTemplate che contiene il controllo sopra ... probabilmente non è il modo migliore per farlo. Sono ancora aperto a idee migliori.