如何仅用XAML实现汉堡菜单过渡动画(无代码后置)
纯XAML实现汉堡菜单切换动画
没问题!完全可以摆脱代码后置实现这个需求,核心思路就是用ToggleButton的IsChecked状态作为开关,配合触发器自动切换对应的动画故事板,不用手动维护状态变量。下面是完整的可运行方案:
完整XAML代码
<Window x:Class="HamburgerMenuDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="汉堡菜单" Height="450" Width="800"> <Window.Resources> <!-- 打开菜单的动画(复用你原有的逻辑) --> <Storyboard x:Key="OpenMenu"> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="rectangle"> <EasingDoubleKeyFrame KeyTime="0" Value="0"/> <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="43.5"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="rectangle1"> <EasingDoubleKeyFrame KeyTime="0" Value="0"/> <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="-43.5"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="rectangle2"> <EasingDoubleKeyFrame KeyTime="0" Value="1"/> <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="GridMenu"> <EasingDoubleKeyFrame KeyTime="0" Value="70"/> <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="200"/> </DoubleAnimationUsingKeyFrames> </Storyboard> <!-- 关闭菜单的动画(复用你原有的逻辑) --> <Storyboard x:Key="CloseMenu"> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="rectangle"> <EasingDoubleKeyFrame KeyTime="0" Value="43.5"/> <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="rectangle1"> <EasingDoubleKeyFrame KeyTime="0" Value="-43.5"/> <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="rectangle2"> <EasingDoubleKeyFrame KeyTime="0" Value="0"/> <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="GridMenu"> <EasingDoubleKeyFrame KeyTime="0" Value="200"/> <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="70"/> </DoubleAnimationUsingKeyFrames> </Storyboard> <!-- 自定义汉堡按钮样式,绑定状态触发动画 --> <Style x:Key="HamburgerButtonStyle" TargetType="ToggleButton"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ToggleButton"> <Grid Width="40" Height="40" Background="Transparent"> <!-- 汉堡菜单的三条横线 --> <Rectangle x:Name="rectangle" Fill="Black" Width="25" Height="3" VerticalAlignment="Top" Margin="0,8,0,0"> <Rectangle.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform/> <TranslateTransform/> </TransformGroup> </Rectangle.RenderTransform> </Rectangle> <Rectangle x:Name="rectangle1" Fill="Black" Width="25" Height="3" VerticalAlignment="Bottom" Margin="0,0,0,8"> <Rectangle.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform/> <TranslateTransform/> </TransformGroup> </Rectangle.RenderTransform> </Rectangle> <Rectangle x:Name="rectangle2" Fill="Black" Width="25" Height="3" VerticalAlignment="Center"/> </Grid> <ControlTemplate.Triggers> <!-- 按钮选中时(打开菜单),执行OpenMenu动画 --> <Trigger Property="IsChecked" Value="True"> <Trigger.EnterActions> <BeginStoryboard Storyboard="{StaticResource OpenMenu}"/> </Trigger.EnterActions> <!-- 按钮取消选中时(关闭菜单),执行CloseMenu动画 --> <Trigger.ExitActions> <BeginStoryboard Storyboard="{StaticResource CloseMenu}"/> </Trigger.ExitActions> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> <Grid> <!-- 菜单容器 --> <Grid x:Name="GridMenu" Width="70" Background="#FF2C3E50" VerticalAlignment="Stretch"> <!-- 汉堡按钮 --> <ToggleButton Style="{StaticResource HamburgerButtonStyle}" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,10,0,0"/> <!-- 这里可以添加你的菜单内容 --> </Grid> <!-- 主内容区域 --> <Grid Margin="70,0,0,0" Background="#ECF0F1"> <!-- 主内容放置在这里 --> </Grid> </Grid> </Window>
核心逻辑解释
- 用ToggleButton代替普通Button:
ToggleButton自带IsChecked属性,天生适合这种“开关”场景,不用自己维护StateClosed变量。 - 触发器绑定状态:
- 当
IsChecked变为True(第一次点击打开菜单),通过Trigger.EnterActions启动OpenMenu故事板 - 当
IsChecked变为False(再次点击关闭菜单),通过Trigger.ExitActions启动CloseMenu故事板
- 当
- 完全复用原有动画:你之前写的两个
Storyboard可以直接复用,不需要修改任何关键帧参数,完美保留原来的动画效果。
这样就实现了完全无代码后置的汉堡菜单切换,所有交互逻辑都在XAML中完成~
内容的提问来源于stack exchange,提问作者Hanebu
相关产品推荐
相关产品推荐

