在“FrameworkElement.Loaded”之后和“Unloaded”之前播放动画(在ListBoxItem中)

时间:2015-05-20 14:01:23

标签: wpf wpf-controls wpf-animation

我有ListBox:

<ListBox x:Name="ListBoxImages"
         ScrollViewer.CanContentScroll="True"
         UseLayoutRounding="False"
         SelectionMode="Extended"/>

ListBox样式:

<Style TargetType="{x:Type ListBox}">
        ...
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBox">
                    <Border Name="Border">
                        <ScrollViewer Focusable="false">
                            <WrapPanel ItemWidth="100"
                                       IsItemsHost="True"/>
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

和ListBoxItem样式(动画在这里,对不起长代码):

<Style TargetType="{x:Type ListBoxItem}">
       <!--...-->
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Border x:Name="border"
                            RenderTransformOrigin="0.5,0.5">
                        <Border.RenderTransform>
                            <TransformGroup>
                                <ScaleTransform x:Name="ScaleTransform"/>
                            </TransformGroup>
                        </Border.RenderTransform>
                        <ContentPresenter/>
                    </Border>

                        <!--Animation-->

                        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="ScaleTransform"
                                                     Storyboard.TargetProperty="ScaleX"
                                                     Duration="0:0:0.1"
                                                     From="0" To="1"/>
                                    <DoubleAnimation Storyboard.TargetName="ScaleTransform"
                                                     Storyboard.TargetProperty="ScaleY"
                                                     Duration="0:0:0.1"
                                                     From="0" To="1"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>

                        <EventTrigger RoutedEvent="FrameworkElement.Unloaded">
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="ScaleTransform"
                                                     Storyboard.TargetProperty="ScaleX"
                                                     Duration="0:0:0.1"
                                                     To="0"/>
                                    <DoubleAnimation Storyboard.TargetName="ScaleTransform"
                                                     Storyboard.TargetProperty="ScaleY"
                                                     Duration="0:0:0.1"
                                                     To="0"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

问题。添加元素(FrameworkElement.Loaded)时的动画并非总是如此。这种感觉是在创建项目但尚未显示时播放的。 删除项目时的动画(FrameworkElement.Unloaded)不会播放。 那么,如何修复呢?

1 个答案:

答案 0 :(得分:2)

您的Loaded故事板已正确定义,因此应该有其他原因,以便有时可以正确播放,有时不会。将新项目添加到列表框时,UI线程上是否存在长期操作?这会导致冻结,因此动画不会一直流畅地播放。

您的Unloaded故事板未播放,因为当从用于渲染整个场景的可视/逻辑树中删除该元素时会引发此事件。这个故事板应该在删除之前启动,但不幸的是没有机制/事件告诉要删除一个项目。

目前,没有简单的方法可以淡出WPF中ItemsControl的项目。在WinRT和Silverlight中,ItemsControl项目有两个独立的可视状态,可用于淡入或淡出。正如Krishna所提到的,唯一的方法是实现自定义功能,告诉项目即将被删除,以及它应该运行淡出动画。在该动画之后,可以从视觉/逻辑树中删除该项目。