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

如何在XAML中设置Material Design PopupBox的自定义打开动画?

实现Material Design PopupBox的自定义打开动画

完全可以实现你想要的缩放式打开动画效果,只需通过重写PopupBox的控件模板,替换默认的滑动动画为缩放+淡入动画即可。以下是具体步骤和代码:

步骤1:创建自定义PopupBox样式

在你的资源字典(如Window/UserControl的Resources节点)中添加以下自定义样式,该样式继承自MaterialDesign的默认PopupBox样式,仅修改动画部分:

<Style x:Key="ScalePopupBoxStyle" TargetType="materialDesign:PopupBox" BasedOn="{StaticResource MaterialDesignPopupBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="materialDesign:PopupBox">
                <Grid>
                    <!-- 保留原有的ToggleButton部分 -->
                    <ToggleButton x:Name="PART_ToggleButton"
                                  Style="{TemplateBinding ToggleButtonStyle}"
                                  IsChecked="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
                                  Content="{TemplateBinding PlaceholderContent}"
                                  HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                                  VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                                  Padding="{TemplateBinding Padding}"
                                  Margin="{TemplateBinding Margin}"
                                  Height="{TemplateBinding Height}"
                                  Width="{TemplateBinding Width}"/>
                    
                    <!-- 修改Popup部分,禁用默认动画并添加缩放变换 -->
                    <Popup x:Name="PART_Popup"
                           Placement="{TemplateBinding PlacementMode}"
                           IsOpen="{Binding IsChecked, ElementName=PART_ToggleButton}"
                           StaysOpen="False"
                           AllowsTransparency="True"
                           PopupAnimation="None">
                        <Border x:Name="PART_PopupContent"
                                Background="{TemplateBinding PopupBackground}"
                                BorderBrush="{TemplateBinding PopupBorderBrush}"
                                BorderThickness="{TemplateBinding PopupBorderThickness}"
                                CornerRadius="{TemplateBinding PopupUniformCornerRadius}"
                                RenderTransformOrigin="1, 0.5"> <!-- 动画原点设为右侧中间,匹配LeftAndAlignMiddles布局 -->
                            <Border.RenderTransform>
                                <ScaleTransform ScaleX="0" ScaleY="0"/> <!-- 初始状态为完全缩小 -->
                            </Border.RenderTransform>
                            <ContentPresenter Content="{TemplateBinding Content}"
                                              Margin="{TemplateBinding PopupContentMargin}"
                                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Border>
                    </Popup>
                </Grid>
                
                <!-- 替换打开/关闭动画 -->
                <ControlTemplate.Triggers>
                    <EventTrigger RoutedEvent="PopupBox.PopupOpening">
                        <BeginStoryboard>
                            <Storyboard>
                                <!-- 缩放动画:从0到1 -->
                                <DoubleAnimation Storyboard.TargetName="PART_PopupContent"
                                                 Storyboard.TargetProperty="RenderTransform.ScaleX"
                                                 From="0" To="1"
                                                 Duration="0:0:0.2"
                                                 EasingFunction="{materialDesign:MaterialDesignEasing}"/>
                                <DoubleAnimation Storyboard.TargetName="PART_PopupContent"
                                                 Storyboard.TargetProperty="RenderTransform.ScaleY"
                                                 From="0" To="1"
                                                 Duration="0:0:0.2"
                                                 EasingFunction="{materialDesign:MaterialDesignEasing}"/>
                                <!-- 淡入动画:从透明到不透明 -->
                                <DoubleAnimation Storyboard.TargetName="PART_PopupContent"
                                                 Storyboard.TargetProperty="Opacity"
                                                 From="0" To="1"
                                                 Duration="0:0:0.2"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                    <EventTrigger RoutedEvent="PopupBox.PopupClosing">
                        <BeginStoryboard>
                            <Storyboard>
                                <!-- 关闭时的缩放+淡出动画 -->
                                <DoubleAnimation Storyboard.TargetName="PART_PopupContent"
                                                 Storyboard.TargetProperty="RenderTransform.ScaleX"
                                                 From="1" To="0"
                                                 Duration="0:0:0.15"
                                                 EasingFunction="{materialDesign:MaterialDesignEasing}"/>
                                <DoubleAnimation Storyboard.TargetName="PART_PopupContent"
                                                 Storyboard.TargetProperty="RenderTransform.ScaleY"
                                                 From="1" To="0"
                                                 Duration="0:0:0.15"
                                                 EasingFunction="{materialDesign:MaterialDesignEasing}"/>
                                <DoubleAnimation Storyboard.TargetName="PART_PopupContent"
                                                 Storyboard.TargetProperty="Opacity"
                                                 From="1" To="0"
                                                 Duration="0:0:0.15"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

步骤2:将样式应用到你的PopupBox

修改你原有的PopupBox代码,添加Style属性引用上述自定义样式:

<materialDesign:PopupBox x:Name="P" 
                         Style="{StaticResource ScalePopupBoxStyle}"
                         PopupUniformCornerRadius="5" 
                         PlacementMode="LeftAndAlignMiddles" 
                         HorizontalAlignment="Right" 
                         Height="34" 
                         Margin="0,22,10,0" 
                         VerticalAlignment="Center">
    <StackPanel>
        <Grid Height="60" Width="90">
            <ToggleButton
                HorizontalAlignment="Right"
                Style="{StaticResource MaterialDesignSwitchToggleButton}"
                ToolTip="Lock/Unlock" Cursor="Hand">
                <materialDesign:ToggleButtonAssist.SwitchTrackOnBackground>
                    <SolidColorBrush Color="DarkSlateGray" />
                </materialDesign:ToggleButtonAssist.SwitchTrackOnBackground>
                <materialDesign:ToggleButtonAssist.SwitchTrackOffBackground>
                    <SolidColorBrush Color="Gray" />
                </materialDesign:ToggleButtonAssist.SwitchTrackOffBackground>
            </ToggleButton>
        </Grid>
        <Button Content="2"/>
        <Button Content="3"/>
    </StackPanel>
</materialDesign:PopupBox>

关键说明

  • RenderTransformOrigin="1,0.5":确保动画从弹窗的右侧中间位置开始缩放,与你设置的PlacementMode="LeftAndAlignMiddles"布局匹配。
  • PopupAnimation="None":禁用WPF默认的Popup动画,避免与自定义动画冲突。
  • 使用{materialDesign:MaterialDesignEasing}:保持动画曲线与Material Design库的默认风格一致。
  • 可根据需求调整动画的Duration值,修改动画的快慢速度。

内容的提问来源于stack exchange,提问作者vahid Araghi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 00:55:13