UWP:分享故事板

时间:2017-09-20 16:27:20

标签: xaml uwp windows-10-universal uwp-xaml

在WPF中,我可以创建一个故事板作为页面/控件资源,然后多次使用它来获取该页面内的控件(或父控件)......

    <Grid Background="{DynamicResource CorporateLogoBackgroundBrush}" views:MainWindowHelper.DragWindowOnMouseDown="True">

        <Grid.Resources>

            <Storyboard x:Key="FlashRedBackgroundStoryboard">
                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Duration="0:0:1" RepeatBehavior="Forever">
                    <ObjectAnimationUsingKeyFrames.KeyFrames>
                        <DiscreteObjectKeyFrame KeyTime="0:0:0.5">
                            <DiscreteObjectKeyFrame.Value>
                                <SolidColorBrush Color="Red" />
                            </DiscreteObjectKeyFrame.Value>
                        </DiscreteObjectKeyFrame>
                    </ObjectAnimationUsingKeyFrames.KeyFrames>
                </ObjectAnimationUsingKeyFrames>
            </Storyboard>

        </Grid.Resources>

        <Border Grid.Column="4" BorderThickness="0">

            <Border.Style>
                <Style TargetType="{x:Type Border}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=IsNetworkConnectivityOk}" Value="false">
                            <DataTrigger.EnterActions>
                                <BeginStoryboard Name="FlashRedBackgroundStoryboard">
                                    <StaticResource  ResourceKey="FlashRedBackgroundStoryboard" />
                                </BeginStoryboard>
                            </DataTrigger.EnterActions>
                            <DataTrigger.ExitActions>
                                <StopStoryboard BeginStoryboardName="FlashRedBackgroundStoryboard"></StopStoryboard>
                            </DataTrigger.ExitActions>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Border.Style>

            <TextBlock Text="LAN/WLAN" />

        </Border>

        <Border Grid.Column="5" BorderThickness="0">

            <Border.Style>
                <Style TargetType="{x:Type Border}">
                    <Setter Property="Background" Value="{DynamicResource CorporateLogoBackgroundBrush}" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=SynchronisationClientService.IsActive}" Value="true">
                            <Setter Property="Background" Value="Green" />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=SynchronisationClientService.IsRunning}" Value="false">
                            <DataTrigger.EnterActions>
                                <BeginStoryboard Name="FlashRedBackgroundStoryboard">
                                    <StaticResource  ResourceKey="FlashRedBackgroundStoryboard" />
                                </BeginStoryboard>
                            </DataTrigger.EnterActions>
                            <DataTrigger.ExitActions>
                                <StopStoryboard BeginStoryboardName="FlashRedBackgroundStoryboard"></StopStoryboard>
                            </DataTrigger.ExitActions>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Border.Style>

            <TextBlock Text="SYNC" />

        </Border>

    </Grid>

但是,我找不到在UWP中做同样事情的方法。在WPF中使用DataTrigger和BeginStoryboard似乎自动关联Storyboard.TargetName,但在UWP中,我必须使用Interactions包,然后尝试将故事板与控件相关联,错误与故事板不与控件关联。 ..

<Grid Background="{StaticResource CorporateBackgroundBrush}">

    <Grid.Resources>

        <Storyboard x:Key="FlashRedBackgroundStoryboard">
            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Duration="0:0:1" RepeatBehavior="Forever">
                <ObjectAnimationUsingKeyFrames.KeyFrames>
                    <DiscreteObjectKeyFrame KeyTime="0:0:0.5">
                        <DiscreteObjectKeyFrame.Value>
                            <SolidColorBrush Color="Red" />
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                </ObjectAnimationUsingKeyFrames.KeyFrames>
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>


    </Grid.Resources>


    <Border Grid.Column="4" BorderThickness="0">

        <interactivity:Interaction.Behaviors>
            <interactionsCore:DataTriggerBehavior Binding="{Binding IsNetworkConnectivityOk}" ComparisonCondition="Equal" Value="false">
                <media:ControlStoryboardAction Storyboard="{StaticResource FlashRedBackgroundStoryboard}" />
            </interactionsCore:DataTriggerBehavior>
        </interactivity:Interaction.Behaviors>

        <TextBlock Text="LAN/WLAN" />

    </Border>

    <Border Grid.Column="5" BorderThickness="0">

        <interactivity:Interaction.Behaviors>
            <interactionsCore:DataTriggerBehavior Binding="{Binding IsNetworkConnectivityOk}" ComparisonCondition="Equal" Value="false">
                <media:ControlStoryboardAction Storyboard="{StaticResource FlashRedBackgroundStoryboard}" />
            </interactionsCore:DataTriggerBehavior>
        </interactivity:Interaction.Behaviors>

        <TextBlock Text="SYNC" />

    </Border>

</Grid>

我能在UWP中找到这样做的唯一方法就是拥有多个相同的故事板,每个故事板都会引用它将影响的控件。

<Grid Background="{StaticResource CorporateBackgroundBrush}">

    <Grid.Resources>

        <Storyboard x:Name="NetworkConnectivityStoryboard">
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="NetworkConnectivityBorder" Storyboard.TargetProperty="Background" Duration="0:0:1" RepeatBehavior="Forever">
                <ObjectAnimationUsingKeyFrames.KeyFrames>
                    <DiscreteObjectKeyFrame KeyTime="0:0:0.5">
                        <DiscreteObjectKeyFrame.Value>
                            <SolidColorBrush Color="Red" />
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                </ObjectAnimationUsingKeyFrames.KeyFrames>
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>

        <Storyboard x:Name="SynchronisationStatusStoryboard">
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SynchronisationStatusBorder" Storyboard.TargetProperty="Background" Duration="0:0:1" RepeatBehavior="Forever">
                <ObjectAnimationUsingKeyFrames.KeyFrames>
                    <DiscreteObjectKeyFrame KeyTime="0:0:0.5">
                        <DiscreteObjectKeyFrame.Value>
                            <SolidColorBrush Color="Red" />
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                </ObjectAnimationUsingKeyFrames.KeyFrames>
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>

    </Grid.Resources>


    <Border x:Name="NetworkConnectivityBorder" Grid.Column="4" BorderThickness="0">

        <interactivity:Interaction.Behaviors>
            <interactionsCore:DataTriggerBehavior Binding="{Binding IsNetworkConnectivityOk}" ComparisonCondition="Equal" Value="false">
                <media:ControlStoryboardAction Storyboard="{StaticResource NetworkConnectivityStoryboard}" />
            </interactionsCore:DataTriggerBehavior>
        </interactivity:Interaction.Behaviors>

        <TextBlock Text="LAN/WLAN" />

    </Border>

    <Border x:Name="SynchronisationStatusBorder" Grid.Column="5" BorderThickness="0">

        <interactivity:Interaction.Behaviors>
            <interactionsCore:DataTriggerBehavior Binding="{Binding IsSynchronisingk}" ComparisonCondition="Equal" Value="false">
                <media:ControlStoryboardAction Storyboard="{StaticResource SynchronisationStatusStoryboard}" />
            </interactionsCore:DataTriggerBehavior>
        </interactivity:Interaction.Behaviors>

        <TextBlock Text="SYNC" />

    </Border>

</Grid>

有没有一种方法可以共享一个故事板,以便它可以用于多个控件(在这个特定的实例中,它是一个状态栏,当关联的视图模型属性具有特定值时,某些元素需要闪烁.I我不敢相信我实际上必须创建多个重复的对象来实现这一点。

感谢。

1 个答案:

答案 0 :(得分:3)

在UWP中,Storyboard一次只能为一个 Target制作动画。从技术上讲,您可以手动停止(即Storyboard.Stop)它,更改其Target属性并再次启动动画(即Storyboard.Begin)。

但是如果你想同时为两个元素制作动画呢?那么这种方法是行不通的。这就是为每个想要设置动画的元素创建新Storyboard的原因。

这是使用附加属性而不是静态XAML的解决方案。这是一些编写代码,但是一旦你进行了设置,它就很容易使用(即一行XAML代码)并且几乎可以与任何元素一起使用。

我们的想法是创建一个名为bool的{​​{1}}属性,该属性可以附加到具有ShowFlashBackground属性的元素,例如Background,{{1}或任何Border

然后,只要此属性设置为Grid(例如,由Control触发),请调用扩展方法true以启动颜色动画。

守则

IsNetworkConnectivityOk

XAML

FlashElementBackground

希望这有帮助!