故事板动画数据触发和反转

Posted

技术标签:

【中文标题】故事板动画数据触发和反转【英文标题】:Storyboard animation datatrigger and reverse 【发布时间】:2020-07-01 12:42:20 【问题描述】:

我有 10 个对象的可观察集合,绑定在 itemscontrol canvas 中。 每个对象都有不同的 canvas.right canvas.top 值。 想法是点击对象来编辑它,对象应该移动到某个位置,编辑它,完成后点击它回到原来的位置。 所以我使用了一个复选框来为动画创建一个数据触发器,我有两个动画一个用于编辑另一个用于返回。 问题是只有第一个动画永远不会触发第二个动画,因此控件永远不会移回其位置。

代码如下:

<ItemsControl ItemsSource="Binding SelectedButtonForEdit.Layers">
                    <ItemsControl.Template>
                        <ControlTemplate TargetType="ItemsControl">
                            <Canvas IsItemsHost="True"/>
                        </ControlTemplate>
                    </ItemsControl.Template>
                    <ItemsControl.ItemContainerStyle>
                        <Style TargetType="ContentPresenter">
                            <Setter Property="Canvas.Right" x:Name="right" Value="Binding CanvasRight"/>
                            <Setter Property="Canvas.Top" x:Name="top" Value="Binding CanvasTop"/>
                            <Setter Property="ContentTemplate">
                                <Setter.Value>
                                    <DataTemplate>
                                        <CheckBox Width="342" Height="156" IsChecked="Binding IsEditing" BorderBrush="Black" BorderThickness="1" Style="StaticResource MaterialDesignRaisedAccentButton" Background="Binding Name,Converter=StaticResource LayerNameToColor" >
                                            <Grid VerticalAlignment="Stretch">
                                                <Grid.RowDefinitions>
                                                    <RowDefinition />
                                                    <RowDefinition Height="3*"/>
                                                    <RowDefinition Height="*"/>
                                            </Grid>
                                        </CheckBox>
                                    </DataTemplate>
                                </Setter.Value>
                            </Setter>
                            <Style.Triggers>
                                <DataTrigger  Binding="Binding IsEditing" Value="False">
                                    <DataTrigger.EnterActions>
                                        <BeginStoryboard>
                                            <Storyboard>
                                                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Right)" Duration="0:0:0:0.1" ></DoubleAnimation>
                                                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)"   Duration="0:0:0:0.1" ></DoubleAnimation>
                                            </Storyboard>
                                        </BeginStoryboard>
                                    </DataTrigger.EnterActions>
                                </DataTrigger>

                            <DataTrigger  Binding="Binding IsEditing" Value="True">
                                    <DataTrigger.ExitActions>
                                        <BeginStoryboard>
                                            <Storyboard>
                                                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Right)"  To="200" Duration="0:0:0:0.1" ></DoubleAnimation>
                                                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)"   To="150" Duration="0:0:0:0.1" ></DoubleAnimation>
                                            </Storyboard>
                                        </BeginStoryboard>
                                    </DataTrigger.ExitActions>
                                </DataTrigger>
                            </Style.Triggers>

                        </Style>
                    </ItemsControl.ItemContainerStyle>
                </ItemsControl>

【问题讨论】:

【参考方案1】:

在您的第一个触发器上,您有一个 EnterActions,而在第二个触发器上,您有一个 ExitActions。但在您的情况下,您只需要 1 个触发器,同时具有 EnterActions 和 ExitActions,如下所示:

<DataTrigger  Binding="Binding IsEditing" Value="True">
    <DataTrigger.EnterActions>
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Right)"  To="200" Duration="0:0:0:0.1" ></DoubleAnimation>
                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)"   To="150" Duration="0:0:0:0.1" ></DoubleAnimation>
            </Storyboard>
        </BeginStoryboard>
    </DataTrigger.EnterActions>
    <DataTrigger.ExitActions>
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Right)" Duration="0:0:0:0.1"></DoubleAnimation>
                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)"   Duration="0:0:0:0.1"></DoubleAnimation>
            </Storyboard>
        </BeginStoryboard>
    </DataTrigger.ExitActions>
</DataTrigger>

在我提供的代码中,当 IsEditing 变为 True 时,动画会将对象移动到 200,150,当 IsEditing 变为 false 时,将返回到原来的值。

【讨论】:

谢谢,但绑定“To”道具会导致 System.InvalidOperationException:'无法冻结此 Storyboard 时间线树以供跨线程使用。' 你可以在这里找到绑定问题的解决方案:***.com/questions/1669750/… 实际上我认为它可以在没有添加 To="Binding CanvasRight" 到退出操作的情况下正常工作......因为如果你调整你的答案,它就会进入原始点,并将其标记为正确跨度>

以上是关于故事板动画数据触发和反转的主要内容,如果未能解决你的问题,请参考以下文章

如何允许完整的 WPF 故事板动画

在将动画名称注册到目标 Frameworkelements 后,将 2+ 故事板的孩子移动到一个故事板

故事板 - 如何在没有动画和显示屏幕的情况下自动执行转场

Silverlight & Blend动画设计系列五:故事板(StoryBoards)和动画(Animations)

Silverlight & Blend动画设计系列五:故事板(StoryBoards)和动画(Animations)

在WPF中,有没有办法在后面的代码中获取故事板动画值的当前值?