2009-11-05 15 views
14

NOTA he hecho la pregunta relacionada (con una respuesta aceptada): How to combine DataTrigger and Trigger?¿Cómo combinar DataTrigger y EventTrigger?

creo que es necesario combinar un EventTrigger y una DataTrigger para conseguir lo que busco:

  • cuando aparece un elemento en mi ListBox, debe parpadear por unos momentos
  • si el elemento es 'Crítico', entonces debe permanecer resaltado

Actualmente tengo un DataTemplate que tiene este aspecto:

<DataTemplate DataType="{x:Type Notifications:NotificationViewModel}"> 
    <Grid HorizontalAlignment="Stretch"> 
     <Border Name="Background" CornerRadius="8" Background="#80c0c0c0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> 
     <Border Name="Highlight" CornerRadius="8" Background="Red"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> 
     <!-- snip actual visual stuff --> 
     <Grid.Triggers> 
      <EventTrigger RoutedEvent="Grid.Loaded"> 
       <EventTrigger.Actions> 
        <BeginStoryboard> 
         <Storyboard> 
          <DoubleAnimation x:Name="LoadedAnimation" 
              Storyboard.TargetName="Highlight" 
              Storyboard.TargetProperty="Opacity" 
              From="0" To="1" 
              RepeatBehavior="5x" 
              Duration="0:00:0.2" 
              AutoReverse="True" /> 
         </Storyboard> 
        </BeginStoryboard> 
       </EventTrigger.Actions> 
      </EventTrigger> 
     </Grid.Triggers> 
    </Grid> 
    <DataTemplate.Triggers> 
     <DataTrigger Binding="{Binding Path=IsCritical}" Value="True"> 
      <Setter TargetName="LoadedAnimation" Property="RepeatBehavior" Value="5.5x" /> 
     </DataTrigger> 
    </DataTemplate.Triggers> 
</DataTemplate> 

La idea es que un EventTrigger anima la opacidad del Highlight de frontera entre 0 y 1 y de nuevo repetidamente cuando el artículo se carga por primera vez, la elaboración del la atención del usuario a ella. El DataTrigger determina el número de veces que se debe animar. Si el modelo de vista informa que el elemento IsCritical, la animación se produce 5,5 veces (de manera que finaliza en opacidad 1); de lo contrario, aparece 5 veces (finaliza en opacidad 0.)

Sin embargo, el XAML anterior no funciona porque el creador del DataTrigger falla con:

No se encontró el nombre Child 'LoadedAnimation' en VisualTree.

Bastante bien. Por lo tanto, a menos que use un convertidor de valor personalizado o que coloque el recuento de animación en el modelo de vista y que sea vinculante para él, ¿cuáles son mis opciones?

+0

Podría ser útil http://stackoverflow.com/questions/2764415/how-to-give-the-condition-for-eventtrigger –

Respuesta

-3

intentar algo como esto:

<Style x:Key="EventTriggerStyleKey"> 
    <Style.Triggers> 
    <EventTrigger RoutedEvent="some event here"> 
     <!-- your animation here --> 
    </EventTrigger> 
    <Style.Triggers> 
</Style> 

<Style x:Key="myStyleKey"> 
    <Style.Triggers> 
    <DataTrigger Binding="....." Value="......"> 
     <Setter Property="........." Value="......."/> 
     <Setter Property="Style" Value="{StaticResource EventTriggerStyleKey}"/> 
    </DataTrigger> 
    <Style.Triggers> 
</Style> 
+4

Has probado esto? Según mi experiencia, no puedes tener un estilo que establezca un estilo. –

+1

No puede establecer un estilo dentro de un estilo –

0

Si tiene acceso al SDK de mezcla (usted debe si usted está utilizando VS2012 +), usted debería ser capaz de lograr esto en su totalidad en XAML, con algo como esto (disclaimer: no probado):

<Grid HorizontalAlignment="Stretch"> 
    <VisualStateManager.VisualStateGroups> 
     <VisualStateGroup x:Name="NotificationStates"> 
      <VisualState x:Name="Flashing"> 
       <Storyboard> 
        <DoubleAnimation x:Name="LoadedAnimation" 
            Storyboard.TargetName="Highlight" 
            Storyboard.TargetProperty="Opacity" 
            From="0" To="1" 
            RepeatBehavior="5x" 
            Duration="0:00:0.2" 
            AutoReverse="True" /> 
       </Storyboard> 
      </VisualState> 
      <VisualState x:Name="Normal" /> 
     </VisualStateGroup> 
    </VisualStateManager.VisualStateGroups> 
    <Border Name="Background" CornerRadius="8" Background="#80c0c0c0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> 
    <Border Name="Highlight" CornerRadius="8" Background="Red"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> 
    <!-- snip actual visual stuff --> 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="Loaded"> 
      <ic:GoToStateAction StateName="Flashing"/> 
     </i:EventTrigger> 
     <ie:DataTrigger Binding="{Binding Path=IsCritical}" Value="True"> 
      <ic:GoToStateAction StateName="Flashing"/> 
     </ie:DataTrigger> 
    </i:Interaction.Triggers> 
</Grid> 

extraer sus Storyboard a un VisualState, a continuación, utilizar la biblioteca de expresión para cambiar estados en el XAML. Necesitará la biblioteca Microsoft.Expression.Interactions, consulte también WPF/Silverlight States - Activate from XAML?

0

En este caso, utilizaría un comportamiento en lugar de triggers. Puede escribir un comportamiento que adjunte un controlador de eventos al evento load del objeto asociado y luego aplique la animación. El comportamiento puede exponer algunas propiedades. Expondría una propiedad de AnimationCount (int) que indica el comportamiento de la cantidad de tiempo para repetir la animación en el elemento al que está asociada. A continuación, puede enlazar esta propiedad a la propiedad IsCritical en el modelo de vista y utilizar un convertidor de valores para convertir falsa a 5 y fiel a 5,5

espero que esto ayude

0

Sé que dijo que no estaban interesados ​​en el idea de un convertidor, pero parece que las soluciones Blend requieren que se instale una biblioteca.El convertidor no es mucho trabajo y señales intención de que la tasa depende directamente de la propiedad IsCritical:

public class CriticalAnimationRateConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     // Error handling omitted for brevity. 
     if ((bool)value) 
      return new System.Windows.Media.Animation.RepeatBehavior(5.5); 
     else 
      return new System.Windows.Media.Animation.RepeatBehavior(5.0); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

y luego actualizar su animación:

<DoubleAnimation Storyboard.TargetName="Highlight" 
       Storyboard.TargetProperty="Opacity" 
       From="0" 
       To="1" 
       RepeatBehavior="{Binding IsCritical, Converter={StaticResource CriticalAnimationRateConverter}}" 
       Duration="0:00:0.2" 
       AutoReverse="True" /> 

la DataTrigger entonces se puede quitar.