2009-11-05 151 views
14

注意我已要求相关的问题(与所接受的答案):How to combine DataTrigger and Trigger?如何结合DataTrigger和EventTrigger?

我想我需要一个EventTrigger结合和DataTrigger达到我所追求的:

  • 当一个项目出现在我的ListBox中时,它应该会闪烁片刻
  • 如果项目是'Critical',那么它应该保持突出显示

目前,我有一个DataTemplate,看起来像这样:

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

的想法是,一个EventTrigger动画的Highlight边界的不透明度0和1之间,然后再返回反复第一次加载项时,绘制用户关注它。 DataTrigger确定动画的次数。如果视图模型报告项目IsCritical则动画出现5.5次(使得它在不透明度1处结束),否则出现5次(在不透明度0处结束)。

然而,上述XAML不起作用,因为DataTrigger的setter失败:

在VisualTree中找不到名为'LoadedAnimation'的子项。

不够公平。因此,使用自定义值转换器或将动画放在视图模型上并绑定到视图模型时,我有什么选择?

+0

这可能是有帮助的http://stackoverflow.com/questions/2764415/how-to-give-the-condition-for-eventtrigger – 2014-01-23 12:35:54

回答

-3

尝试这样:

<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

你试过吗?这是我的经验,你不能有一个风格设定风格。 – 2009-11-09 17:54:32

+1

您不能在样式中设置样式 – 2011-09-23 03:58:48

0

如果你有机会到混和SDK(你应该,如果你正在使用VS2012 +),你应该能够在XAML完全做到这一点,像这样的东西(免责声明:未经测试):

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

提取你的故事板到的VisualState,然后使用表达式库的XAML中切换状态。您需要Microsoft.Expression.Interactions库,另请参阅WPF/Silverlight States - Activate from XAML?

0

在这种情况下,我将使用行为而不是触发器。您可以编写一个行为,将事件处理程序附加到关联的对象的加载事件,然后应用动画。该行为可能会暴露一些属性,我会公开一个AnimationCount(int)属性,该属性告诉行为有多少时间在与其关联的元素上重复动画。然后,您可以将此属性设置为IsCritical属性绑定在视图模型,并使用值转换器转换成假以5和真实的5.5

希望这有助于

0

我知道你说你不热衷于一个转换器的想法,但它看起来像混合解决方案需要安装一个库。该转换器是没有太多的工作和信号的意图,房价是直接依赖于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(); 
    } 
} 

,然后更新您的动画:

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

DataTrigger然后可以去除。