如何DataTrigger和EventTrigger结合?

问题描述 投票:15回答:4

注:我已要求相关的问题(与所接受的答案):How to combine DataTrigger and Trigger?

我想我需要一个EventTriggerDataTrigger达到什么样的我后我结合:

  • 当一个项目出现在我的列表框,它应闪烁片刻
  • 如果该项目是“严重”,那么它应该仍然突出

目前,我有一个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动画0和1之间来回反复,当第一次加载项,将用户的注意力,以它的Highlight边界的不透明度。所述DataTrigger确定的倍动画数。如果视图模型报告该项目IsCritical那么动画发生5.5倍(例如,它在不透明度1结束),否则它发生5次(不透明度为0。结尾)

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

儿童与名称“LoadedAnimation”中的VisualTree没有找到。

很公平。因此,害羞使用自定义值转换器,或将动画计数的视图模型,并结合它的,有哪些选择?

.net wpf xaml triggers datatrigger
4个回答
0
投票

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

希望这可以帮助


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

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


-4
投票

尝试是这样的:

<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>
© www.soinside.com 2019 - 2024. All rights reserved.