【问题标题】:UWP Add animation on ItemsControl itemsUWP 在 ItemsControl 项目上添加动画
【发布时间】:2017-02-14 00:40:07
【问题描述】:

上面是我在 UWP 中的静态页面上的模拟动画。 这是模拟的 XAML 代码

<Page.Resources>
    <Storyboard x:Name="GridViewButtonPointerEnteredAnimation">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="GridViewButtonBackdrop">
            <EasingDoubleKeyFrame KeyTime="0" Value="0.1"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1">
                <EasingDoubleKeyFrame.EasingFunction>
                    <QuadraticEase EasingMode="EaseInOut"/>
                </EasingDoubleKeyFrame.EasingFunction>
            </EasingDoubleKeyFrame>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames EnableDependentAnimation="True" Storyboard.TargetProperty="(FrameworkElement.MaxHeight)" Storyboard.TargetName="textBlock">
            <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="100">
                <EasingDoubleKeyFrame.EasingFunction>
                    <QuadraticEase EasingMode="EaseInOut"/>
                </EasingDoubleKeyFrame.EasingFunction>
            </EasingDoubleKeyFrame>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
    <Storyboard x:Name="GridViewButtonPointerExitAnimation">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="GridViewButtonBackdrop">
            <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0">
                <EasingDoubleKeyFrame.EasingFunction>
                    <QuadraticEase EasingMode="EaseInOut"/>
                </EasingDoubleKeyFrame.EasingFunction>
            </EasingDoubleKeyFrame>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames EnableDependentAnimation="True" Storyboard.TargetProperty="(FrameworkElement.MaxHeight)" Storyboard.TargetName="textBlock">
            <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="40">
                <EasingDoubleKeyFrame.EasingFunction>
                    <QuadraticEase EasingMode="EaseInOut"/>
                </EasingDoubleKeyFrame.EasingFunction>
            </EasingDoubleKeyFrame>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
</Page.Resources>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid Margin="10">
        <Grid x:Name="grid" Width="286" Height="286">
            <Grid.Background>
                <ImageBrush Stretch="UniformToFill" ImageSource="ms-appx:///Assets/home/home_mydesk.jpg"/>
            </Grid.Background>

            <Border x:Name="GridViewButtonBackdrop" Background="Transparent" />

            <Border VerticalAlignment="Bottom">
                <Border.Background>
                    <ImageBrush ImageSource="ms-appx:///Assets/boxfade.png" Stretch="Fill" />
                </Border.Background>

                <StackPanel Margin="20,20">
                    <TextBlock Text="My Desk" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left" TextWrapping="Wrap" TextTrimming="WordEllipsis" FontSize="17" FontWeight="Bold" />
                    <TextBlock x:Name="textBlock" Text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum." Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left" TextWrapping="Wrap" TextTrimming="CharacterEllipsis" MaxHeight="40" />

                    <StackPanel Orientation="Horizontal" Margin="0,10,0,0">
                        <Image Source="ms-appx:///Assets/pdf_16.png" Width="16" Height="16" />
                        <TextBlock Text="PDF File" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left" TextWrapping="Wrap" TextTrimming="WordEllipsis" Margin="10,0,0,0" />
                    </StackPanel>
                </StackPanel>
            </Border>

            <Interactivity:Interaction.Behaviors>
                <Core:EventTriggerBehavior EventName="PointerEntered">
                    <Media:ControlStoryboardAction Storyboard="{StaticResource GridViewButtonPointerEnteredAnimation}"/>
                </Core:EventTriggerBehavior>
                <Core:EventTriggerBehavior EventName="PointerExited">
                    <Media:ControlStoryboardAction Storyboard="{StaticResource GridViewButtonPointerExitAnimation}"/>
                </Core:EventTriggerBehavior>
            </Interactivity:Interaction.Behaviors>
        </Grid>
    </Grid>
</Grid>

所以我在我的 ItemsControl.ItemTemplate 上实现了它。我运行了应用程序,但是当我将鼠标悬停在一个项目上时,会出现一个错误并提示。

System.Runtime.InteropServices.COMException: No installed components were detected.

Cannot resolve TargetName GridViewButtonBackdrop.
   at Windows.UI.Xaml.Media.Animation.Storyboard.Begin()
   at Microsoft.Xaml.Interactions.Media.ControlStoryboardAction.Execute(Object sender, Object parameter)
   at Microsoft.Xaml.Interactivity.Interaction.ExecuteActions(Object sender, ActionCollection actions, Object parameter)
   at Microsoft.Xaml.Interactions.Core.EventTriggerBehavior.OnEvent(Object sender, Objec

这是 ItemsControl.ItemTemplate.DataTemplate 的 XAML 实现

<Grid Width="286" Height="286" Background="{StaticResource DefaultThemeColor}">
    <Grid>
        <Image Source="ms-appx:///Assets/icon_pdf.png" Stretch="UniformToFill"  Visibility="{Binding Converter={StaticResource IsPDF},ConverterParameter=pdf}"/>
        <Image Source="ms-appx:///Assets/interactive_placeholder.png" Stretch="UniformToFill"  Visibility="{Binding Converter={StaticResource IsPDF}, ConverterParameter=interactive}"/>
        <Image Source="{Binding image.data.full_path}" Stretch="UniformToFill" />
    </Grid>

    <Border x:Name="GridViewButtonBackdrop" Background="Transparent" />

    <Border MinHeight="0" VerticalAlignment="Bottom">
        <Border.Background>
            <ImageBrush ImageSource="ms-appx:///Assets/boxfade.png" Stretch="Fill" />
        </Border.Background>

        <StackPanel Margin="20,20">
            <TextBlock Text="{Binding title}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left" TextWrapping="Wrap" TextTrimming="WordEllipsis" FontSize="17" FontWeight="Bold" />
            <TextBlock Text="{Binding info.data.description}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left" TextWrapping="Wrap" TextTrimming="WordEllipsis" MaxHeight="40" />

            <StackPanel Orientation="Horizontal" Margin="0,8,0,0" Visibility="{Binding Converter={StaticResource IsPDF},ConverterParameter=pdf}">
                <Image Source="ms-appx:///Assets/pdf_16.png" Width="16" Height="16" />
                <TextBlock Text="PDF File" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left" TextWrapping="Wrap" TextTrimming="WordEllipsis" Margin="10,0,0,0" />
            </StackPanel>

            <StackPanel Orientation="Horizontal" Margin="0,8,0,0" Visibility="{Binding Converter={StaticResource IsPDF}, ConverterParameter=interactive}">
                <Image Source="ms-appx:///Assets/icon_interactive.png" Width="16" Height="16" />
                <TextBlock Text="Interactive" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left" TextWrapping="Wrap" TextTrimming="WordEllipsis" Margin="10,0,0,0" />
            </StackPanel>
        </StackPanel>
    </Border>

    <Interactivity:Interaction.Behaviors>
        <Core:EventTriggerBehavior EventName="PointerEntered">
            <Media:ControlStoryboardAction Storyboard="{StaticResource GridViewButtonPointerEnteredAnimation}"/>
        </Core:EventTriggerBehavior>
        <Core:EventTriggerBehavior EventName="PointerExited">
            <Media:ControlStoryboardAction Storyboard="{StaticResource GridViewButtonPointerExitAnimation}"/>
        </Core:EventTriggerBehavior>
    </Interactivity:Interaction.Behaviors>
</Grid>

我了解它可能看不到该 GridViewButtonBackdrop 元素,因为它位于项目集合中。

如何在我的 ItemsControl 项目中正确实现此动画?

-- 更新--

感谢 @JustinXL 的优化提示。我将 ItemsControl 改成 ListView 并优化动画。

现在就到这里

XAML

<Page.Resources>
    <Storyboard x:Name="GridViewButtonPointerEnteredAnimation">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="GridViewButtonBackdrop">
            <EasingDoubleKeyFrame KeyTime="0" Value="0.1"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1">
                <EasingDoubleKeyFrame.EasingFunction>
                    <QuadraticEase EasingMode="EaseInOut"/>
                </EasingDoubleKeyFrame.EasingFunction>
            </EasingDoubleKeyFrame>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="Description">
            <EasingDoubleKeyFrame KeyTime="0" Value="115"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0">
                <EasingDoubleKeyFrame.EasingFunction>
                    <QuadraticEase EasingMode="EaseInOut"/>
                </EasingDoubleKeyFrame.EasingFunction>
            </EasingDoubleKeyFrame>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="TextDescription">
            <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="0.0001">
                <EasingDoubleKeyFrame.EasingFunction>
                    <QuadraticEase EasingMode="EaseInOut"/>
                </EasingDoubleKeyFrame.EasingFunction>
            </EasingDoubleKeyFrame>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="textBlock">
            <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="43">
                <EasingDoubleKeyFrame.EasingFunction>
                    <QuadraticEase EasingMode="EaseInOut"/>
                </EasingDoubleKeyFrame.EasingFunction>
            </EasingDoubleKeyFrame>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>

    <Storyboard x:Name="GridViewButtonPointerExitAnimation">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="GridViewButtonBackdrop">
            <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0">
                <EasingDoubleKeyFrame.EasingFunction>
                    <QuadraticEase EasingMode="EaseInOut"/>
                </EasingDoubleKeyFrame.EasingFunction>
            </EasingDoubleKeyFrame>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="Description">
            <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="115">
                <EasingDoubleKeyFrame.EasingFunction>
                    <QuadraticEase EasingMode="EaseInOut"/>
                </EasingDoubleKeyFrame.EasingFunction>
            </EasingDoubleKeyFrame>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="TextDescription">
            <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="1">
                <EasingDoubleKeyFrame.EasingFunction>
                    <QuadraticEase EasingMode="EaseInOut"/>
                </EasingDoubleKeyFrame.EasingFunction>
            </EasingDoubleKeyFrame>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="textBlock">
            <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0">
                <EasingDoubleKeyFrame.EasingFunction>
                    <QuadraticEase EasingMode="EaseInOut"/>
                </EasingDoubleKeyFrame.EasingFunction>
            </EasingDoubleKeyFrame>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
</Page.Resources>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid Margin="10">
        <Grid x:Name="grid" Width="286" Height="286">
            <Grid.Clip>
                <RectangleGeometry Rect="0,0,286,286" />
            </Grid.Clip>
            <Grid.Background>
                <ImageBrush Stretch="UniformToFill" ImageSource="ms-appx:///Assets/home/home_mydesk.jpg"/>
            </Grid.Background>

            <Border x:Name="GridViewButtonBackdrop" Background="#AF000000" Opacity="0" />

            <Border VerticalAlignment="Bottom" Height="150">
                <Border.Background>
                    <ImageBrush ImageSource="ms-appx:///Assets/boxfade.png" Stretch="Fill" />
                </Border.Background>
            </Border>

            <Border x:Name="Description" VerticalAlignment="Bottom" RenderTransformOrigin="0.5,0.5">
                <Border.RenderTransform>
                    <CompositeTransform TranslateY="115"/>
                </Border.RenderTransform>
                <StackPanel Margin="20,20">
                    <TextBlock x:Name="textBlock" Text="My Desk" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left" TextWrapping="Wrap" TextTrimming="WordEllipsis" FontSize="17" FontWeight="Bold" RenderTransformOrigin="0.5,0.5" >
                        <TextBlock.RenderTransform>
                            <CompositeTransform/>
                        </TextBlock.RenderTransform>
                    </TextBlock>
                    <TextBlock x:Name="TextDescription" Text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum." Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left" TextWrapping="Wrap" TextTrimming="CharacterEllipsis" MaxHeight="43" Margin="0,5,0,0" RenderTransformOrigin="0.5,0.5"  />

                    <StackPanel Orientation="Horizontal" Margin="0,8,0,0">
                        <Image Source="ms-appx:///Assets/pdf_16.png" Width="16" Height="16" />
                        <TextBlock Text="PDF File" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left" TextWrapping="Wrap" TextTrimming="WordEllipsis" Margin="10,0,0,0" />
                    </StackPanel>

                    <TextBlock x:Name="TextDescriptionExpanded" Text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum." Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Left" TextWrapping="Wrap" TextTrimming="CharacterEllipsis" MaxHeight="100" Margin="0,5,0,0" />
                </StackPanel>
            </Border>

            <Interactivity:Interaction.Behaviors>
                <Core:EventTriggerBehavior EventName="PointerEntered">
                    <Media:ControlStoryboardAction Storyboard="{StaticResource GridViewButtonPointerEnteredAnimation}"/>
                </Core:EventTriggerBehavior>
                <Core:EventTriggerBehavior EventName="PointerExited">
                    <Media:ControlStoryboardAction Storyboard="{StaticResource GridViewButtonPointerExitAnimation}"/>
                </Core:EventTriggerBehavior>
            </Interactivity:Interaction.Behaviors>
        </Grid>
    </Grid>
</Grid>

【问题讨论】:

  • 我制作了一个 UserControl 并且动画效果很好。但我认为这会伤害一些低端设备。 ItemsControl中每个项目的故事板?我的应用程序在 Itemscontrol 中可能有超过 10 或 50 个项目,每个项目中都会有 StoryBoard。

标签: windows xaml uwp


【解决方案1】:

不,将其包装在 UserControl 中不应影响整体性能。这实际上就是我将如何实现它。如果您想要进一步优化,请考虑将您的 ItemsControl 替换为 ListView,这会在默认情况下为您提供 UI 虚拟化(例如,它只会呈现您所看到的内容以及更多内容)。

但是,更会损害性能的是您正在为MaxHeight 属性设置动画,这可能会导致布局更新。这种类型的动画被称为 dependent 动画,它在 UI 线程上运行。尽量避免它们。

所以这里有一个简单的解决方法 -

  1. 复制文本,使复制的文本跨越更多行,然后通过更改其TranslateY 将其向下推以与原始文本对齐,然后默认隐藏它。
  2. 将鼠标悬停在上方时,隐藏原件并显示复制件,然后为其TranslateY 设置动画以将其显示出来。

请注意,TranslateYCompositeTransform 的一部分,不会导致任何代价高昂的布局更新。

【讨论】:

  • 好东西!那时我对动画有另一个想法。你非常了解你的 XAML :) 谢谢!
猜你喜欢
  • 1970-01-01
  • 2013-06-03
  • 2016-02-18
  • 2016-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多