Pregunta

Esta es una situación que surge a menudo:

En la vista, usted tiene un control enlazado a una propiedad ViewModel (respaldado por una INotifyPropertyChanged). Por ejemplo:

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

Cuando los cambios de propiedad, que tiene que traer la atención del usuario al hecho con un poco de animación creativa. ¿Cómo puedo utilizar el hecho de que la vista ya está conectado a la notificación y evitar la creación de la mayor parte del código adicional (o al menos crear una vez y reutilización). disparadores de datos son probablemente la mejor opción, pero no saben cómo hacer que se disparan sobre cualquier cambio de valor frente de algún valor específico.

Las siguientes opciones vienen a la mente:

  • provocar un evento adicional en el modelo de vista, suscríbase en la vista de código subyacente.
  • crear un DataTrigger unido a la propiedad mencionada utilizando un convertidor que devolvería verdadero si el valor está cambiando.
  • crear un DataTrigger unido a una nueva propiedad booleana en el modelo de vista que se utiliza para "señal" del cambio.
  • crear un comportamiento adjunto al control que suscribirse a cambio de propiedad de dependencia del control y comenzar la animación.

¿Cuál te gusta / usa? ¿Me he perdido cualquier opción?

P.S. Sería bueno (pero no crítica) si la solución sería una posibilidad para iniciar la animación anterior que recojan el cambio de valor cuando se terminó.

¿Fue útil?

Solución

Ok, esto es lo que vine a después de un poco de experimentación.

He creado una Expression Blend 3 gatillo con una propiedad de dependencia (lo he denominado suscripción). Ato la suscripción al mismo valor que mi TextBlock está obligado a este disparador y se une a un ControlStoryboardAction de Expression Blend 3.

Aquí está el gatillo:

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);
    }
}

Así es como se adjunta al guión:

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

Me gusta este enfoque mucho, gran mezcla de trabajo 3 diseñadores!

Editar: respondiendo comentario a Drew ...

Sí, se distribuye con Blend. Usted sólo puede incluir Microsoft.Expression.Interactions.dll y System.Windows.Interactivity en su proyecto.

Y sí, es prolijo (He preguntado si alguien descubrió una buena manera de aplicar comportamientos a través de Estilos en esta pregunta ) - pero también es una ventaja de la flexibilidad. Por ejemplo, usted no sólo puede iniciar un guión gráfico, sino también cambiar un estado o realizar alguna otra acción de la misma gatillo.

Otros consejos

Se puede crear un disparador que va a iniciar la animación.

Algo como esto:

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

En cuanto a la cuestión de la cuestión de establecer el valor una vez que la animación se ha completado, esto es un poco de dolor. Por lo que yo soy consciente de que había necesidad de utilizar el evento completado en el guión gráfico, esto requiere código detrás, que es algo que desea evitar con MVVM.

He intentado usar Eventtriggers para unirse a los eventos completados, pero que también introduce algunas complicaciones. Ver aquí para más detalles.

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