.net 如何组合DataTrigger和EventTrigger?

.net 如何组合DataTrigger和EventTrigger?,.net,wpf,xaml,triggers,datatrigger,.net,Wpf,Xaml,Triggers,Datatrigger,注意我已经提出了相关问题(并给出了公认的答案): 我想我需要将EventTrigger和DataTrigger结合起来,以实现我的目标: 当一个项目出现在我的列表框中时,它会闪烁几分钟 如果项目为“关键”,则应保持突出显示 目前,我有一个数据模板,如下所示: <DataTemplate DataType="{x:Type Notifications:NotificationViewModel}"> <Grid HorizontalAlignment="Stretch

注意我已经提出了相关问题(并给出了公认的答案):

我想我需要将
EventTrigger
DataTrigger
结合起来,以实现我的目标:

  • 当一个项目出现在我的列表框中时,它会闪烁几分钟
  • 如果项目为“关键”,则应保持突出显示
目前,我有一个数据模板,如下所示:

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

其思想是EventTrigger在0和1之间为
高亮显示
边框的不透明度设置动画,并在首次加载项目时重复设置,以吸引用户的注意力。
DataTrigger
确定设置动画的次数。如果视图模型报告项目
IsCritical
,则动画会出现5.5次(以不透明度1结束),否则会出现5次(以不透明度0结束)

但是,上述XAML不起作用,因为DataTrigger的setter在以下情况下失败:

在VisualTree中找不到名为“LoadedAnimation”的子级


很公平。因此,在使用自定义值转换器或将动画计数放在视图模型上并绑定到它之前,我的选项是什么?

尝试以下方法:

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

如果您有权访问Blend SDK(如果您使用的是VS2012+),那么您应该能够完全在XAML中完成这项工作,使用类似以下内容(免责声明:未经测试):



将情节提要提取到VisualState,然后使用表达式库在XAML中切换状态。您需要Microsoft.Expression.Interactions库,另请参见

在本例中,我将使用行为而不是触发器。您可以编写一个行为,将事件处理程序附加到关联对象的加载事件,然后应用动画。该行为可能会公开一些属性,我会公开一个AnimationCount(int)属性,该属性告诉该行为在与其关联的元素上重复动画的次数。然后可以将此属性绑定到视图模型中的IsCritical属性,并使用值转换器将false转换为5,将true转换为5.5


希望这能有所帮助

我知道你说过你对转换器的想法不感兴趣,但混合解决方案似乎需要安装一个库。转换器的工作量不大,并且表示速率直接取决于
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

您尝试过吗?根据我的经验,你不能用一种风格来设定一种风格。你不能在一种风格中设定一种风格。这可能会有帮助