You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让WPF中Storyboard/DoubleAnimation的元素从中心缩放

实现WPF列表项中心放大的悬停动画(XAML方案)

问题描述

我是WPF新手,当前项目使用WPF-UI,已成功创建带有DataTemplate的列表。希望实现鼠标悬停时列表项从中心放大的效果(参考微软WPFSample示例),但当前动画从左上角开始。优先希望通过XAML实现,而非C#后台代码。

原ListView代码:

<ui:ListView x:Name="ActressListView"
              ItemsSource="{Binding ViewModel.ActressList}"
              ItemTemplate="{StaticResource ActressItemTemplate}"
              ItemsPanel="{StaticResource ActressPanelTemplate}">
     <behaviors:Interaction.Triggers>
         <behaviors:EventTrigger EventName="SelectionChanged">
             <behaviors:InvokeCommandAction PassEventArgsToCommand="True"
                                            Command="{Binding ViewModel.ActressItemClickedCommand}" />
         </behaviors:EventTrigger>
     </behaviors:Interaction.Triggers>
 </ui:ListView>

原DataTemplate代码:

<DataTemplate x:Key="ActressItemTemplate"
              DataType="{x:Type core:Actress}">
    <StackPanel Margin="8">
        <Border Width="225"
                Height="300"
                Background="{ui:ThemeResource TextFillColorDisabledBrush}"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                RenderTransformOrigin="0.5, 0.5">
            <Border.Triggers>
                <EventTrigger RoutedEvent="Mouse.MouseEnter">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Duration="0:0:0.2"
                                                 Storyboard.TargetProperty="Width"
                                                 To="262.5" />
                                <DoubleAnimation Duration="0:0:0.2"
                                                 Storyboard.TargetProperty="Height"
                                                 To="350" />
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
                <EventTrigger RoutedEvent="Mouse.MouseLeave">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Duration="0:0:0.2"
                                                 Storyboard.TargetProperty="Width"
                                                 To="225" />
                                <DoubleAnimation Duration="0:0:0.2"
                                                 Storyboard.TargetProperty="Height"
                                                 To="300" />
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
            </Border.Triggers>
            <ui:Image Stretch="UniformToFill"
                      Source="{Binding ActressImgUrl}" />
        </Border>
        <ui:TextBlock Text="{Binding Path=FullName}"
                      HorizontalAlignment="Center"
                      Foreground="{ui:ThemeResource TextFillColorSecondaryBrush}"
                      FontTypography="BodyStrong" />
        <ui:TextBlock Text="{Binding Path=AltName}"
                      HorizontalAlignment="Center"
                      Foreground="{ui:ThemeResource TextFillColorSecondaryBrush}"
                      FontTypography="Body" />
    </StackPanel>
</DataTemplate>

解决方案

直接动画Width和Height会让控件从左上角向外扩展,要实现中心放大,需使用ScaleTransform,结合已设置的RenderTransformOrigin="0.5,0.5"(中心原点)来完成动画。

修改后的DataTemplate代码:

<DataTemplate x:Key="ActressItemTemplate"
              DataType="{x:Type core:Actress}">
    <StackPanel Margin="8">
        <Border Width="225"
                Height="300"
                Background="{ui:ThemeResource TextFillColorDisabledBrush}"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                RenderTransformOrigin="0.5, 0.5">
            <!-- 添加ScaleTransform作为渲染变换 -->
            <Border.RenderTransform>
                <ScaleTransform x:Name="ItemScaleTransform" ScaleX="1" ScaleY="1"/>
            </Border.RenderTransform>
            
            <Border.Triggers>
                <EventTrigger RoutedEvent="Mouse.MouseEnter">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <!-- 动画ScaleX和ScaleY实现中心放大 -->
                                <DoubleAnimation Duration="0:0:0.2"
                                                 Storyboard.TargetName="ItemScaleTransform"
                                                 Storyboard.TargetProperty="ScaleX"
                                                 To="1.1667" />
                                <DoubleAnimation Duration="0:0:0.2"
                                                 Storyboard.TargetName="ItemScaleTransform"
                                                 Storyboard.TargetProperty="ScaleY"
                                                 To="1.1667" />
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
                <EventTrigger RoutedEvent="Mouse.MouseLeave">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <!-- 还原缩放比例 -->
                                <DoubleAnimation Duration="0:0:0.2"
                                                 Storyboard.TargetName="ItemScaleTransform"
                                                 Storyboard.TargetProperty="ScaleX"
                                                 To="1" />
                                <DoubleAnimation Duration="0:0:0.2"
                                                 Storyboard.TargetName="ItemScaleTransform"
                                                 Storyboard.TargetProperty="ScaleY"
                                                 To="1" />
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
            </Border.Triggers>
            <ui:Image Stretch="UniformToFill"
                      Source="{Binding ActressImgUrl}" />
        </Border>
        <ui:TextBlock Text="{Binding Path=FullName}"
                      HorizontalAlignment="Center"
                      Foreground="{ui:ThemeResource TextFillColorSecondaryBrush}"
                      FontTypography="BodyStrong" />
        <ui:TextBlock Text="{Binding Path=AltName}"
                      HorizontalAlignment="Center"
                      Foreground="{ui:ThemeResource TextFillColorSecondaryBrush}"
                      FontTypography="Body" />
    </StackPanel>
</DataTemplate>

关键说明

  1. RenderTransformOrigin="0.5,0.5"已设置,确保缩放以Border中心为原点
  2. 使用ScaleTransform替代直接修改Width/Height,ScaleX和ScaleY设为1.1667对应原尺寸的放大比例(262.5/225=1.1667,350/300≈1.1667)
  3. 通过Storyboard.TargetName指定动画目标为ScaleTransform实例,保证仅缩放Border内容且中心对齐

内容的提问来源于stack exchange,提问作者Khanh Khanhh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 21:48:11