¿Cómo puedo tener un WPF EventTrigger en un desencadenador de vista cuando el modelo de vista subyacente lo dicta?

StackOverflow https://stackoverflow.com/questions/1424202

  •  07-07-2019
  •  | 
  •  

Pregunta

Aquí está el escenario:

Tengo el siguiente control de usuario, la idea es que su modelo de vista debería ser capaz de indicarle a la vista que necesita "Activar el resplandor", y así reproducir el 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>

en el código detrás de UnitView, tengo:

public event EventHandler ActivateGlow;

y como es bastante normal en MVVM, tengo el siguiente DataTemplate para UnitViewModel:

<DataTemplate DataType="{x:Type vm:UnitViewModel}">
    <vw:UnitView d:DesignWidth="150" d:DesignHeight="100" />
</DataTemplate>

La pregunta ulitmate es, ¿cómo puedo configurar algo para que el modelo de vista pueda activar el evento OnActivateGlow?

¿Fue útil?

Solución

Actualización: Firoso, como se menciona en los comentarios, debería poder (creo, es decir, no probado) poder usar los componentes de comportamiento de mezcla para cubrir sus necesidades.

Además de descargar e instalar el SDK. Obtenga una copia de la biblioteca de muestras de mezcla de expresiones (deberá hacer clic en Descargas desde el siguiente enlace): Muestras de mezcla de expresiones

Esta biblioteca contiene un activador preconstruido llamado 'DataEventTrigger' que puede usar para activar acciones en respuesta a un evento declarado en su modelo de vista.

El SDK de mezcla ya tiene (por lo que puedo decir) la otra pieza del rompecabezas: ya incluye una acción que le permite controlar los guiones gráficos. El nombre de esta acción es 'ControlStoryboardAction'.

Deberías terminar con algo de xaml que se ve así:

    <i:Interaction.Triggers>
        <samples:DataEventTrigger EventName="YourEvent">
            <im:ControlStoryboardAction Storyboard="{StaticResource Storyboard1}" 
                   ControlStoryboardOption="Play"/>
        </samples:DataEventTrigger>
    </i:Interaction.Triggers>

Reemplace 'YourEvent' con el nombre del evento que ha definido en su modelo de vista y reemplace 'Storyboard1' con el nombre de su storyboard. Por supuesto, los nombres tendrán que coincidir exactamente.

Estas son las definiciones de espacio de nombres xaml utilizadas:

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"

Publicación original, antes de editar:

Sugiero que busque en Comportamientos de combinación de expresiones:

información

Blend SDK

video sobre comportamientos

Otros consejos

También puede poner una propiedad booleana IsGlowing en su modelo de vista y usar disparadores de datos en su estilo

<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>  

Creo que tendría que unirse a un RoutedEvent instancia, no un evento CLR.

No lo he probado, pero algo como esto debería funcionar:

public class UnitView
{
    public static readonly RoutedEvent ActivateGlowEvent
        = EventManager.RegisterRoutedEvent(
              "ActivateGlow", RoutingStrategy.Bubble,
              typeof(RoutedEventHandler), typeof(UnitView)
          );

    public void RaiseActivateGlowEvent()
    {
        RaiseEvent(new RoutedEventArgs(ActivateGlowEvent));
    }
}

Una forma de resolver esto es utilizar un activador de datos en un DataTemplate que contenga el control anterior ... probablemente no sea la mejor manera de hacerlo. Todavía estoy abierto a mejores ideas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top