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

Playing the animation after "FrameworkElement.Loaded" and before "Unloaded" (in ListBoxItem)

我有列表框:

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

列表框样式:

<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)不播放。 那么,如何解决呢?

你的Loaded故事板定义正确,因此有时播放正确有时不正确应该还有其他原因。列表框添加新项时,UI线程是否有长活操作?这会导致卡顿,导致动画无法一直流畅播放。

你的 Unloaded 故事板没有播放 因为当元素从用于呈现整个场景的视觉/逻辑树中移除时会引发此事件 。这个故事板应该在这个移除之前开始,但不幸的是没有机制/事件告诉一个项目要被移除。

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