我正在尝试实现与 VS2012 设置窗口相同的动画,以一种很好的动画方式自动调整大小并以每个内容大小变化为中心。
问题是它不能纯粹通过代码来完成,因为我不知道最终的窗口大小(因为我依赖 SizeToContent="WidthAndHeight"),但是让 SizeToContent="WidthAndHeight" 由它自己不允许我动画过渡
有什么办法吗?
我正在尝试实现与 VS2012 设置窗口相同的动画,以一种很好的动画方式自动调整大小并以每个内容大小变化为中心。
问题是它不能纯粹通过代码来完成,因为我不知道最终的窗口大小(因为我依赖 SizeToContent="WidthAndHeight"),但是让 SizeToContent="WidthAndHeight" 由它自己不允许我动画过渡
有什么办法吗?
我认为实现这一点的最简单方法是在窗口类中使用自定义视觉状态。我做了一个小测试项目,你可以在这里下载:https ://dl.dropboxusercontent.com/u/14810011/ResizingWindow.zip
您需要 Visual Studio 2012 来执行它。
主窗口 XAML 如下所示:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ResizingWindow"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
x:Name="Window" x:Class="ResizingWindow.MainWindow"
Title="MainWindow" Width="350" Height="300" WindowStyle="None" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ExtendedStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.6">
<VisualTransition.GeneratedEasingFunction>
<CubicEase EasingMode="EaseOut"/>
</VisualTransition.GeneratedEasingFunction>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="TextBlock">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="Window">
<EasingDoubleKeyFrame KeyTime="0" Value="300"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Extended">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="Window">
<EasingDoubleKeyFrame KeyTime="0" Value="400"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="TextBlock">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition Height="300"/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<Border Background="#FF6C6C6C">
<Grid>
<TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="Hey, I here is some really cool content." VerticalAlignment="Top" FontSize="32" FontFamily="Segoe UI Light" TextAlignment="Center" Margin="0,50,0,0"/>
<CheckBox Content="I want to see more" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,15" IsChecked="{Binding ShowAdditionalContent}">
<i:Interaction.Behaviors>
<ei:DataStateBehavior Binding="{Binding ShowAdditionalContent}" Value="False" TrueState="Normal" FalseState="Extended"/>
</i:Interaction.Behaviors>
</CheckBox>
<Button Content="" HorizontalAlignment="Right" VerticalAlignment="Top" FontFamily="Segoe UI Symbol" FontSize="21.333" Style="{DynamicResource ButtonStyle}" Margin="0,5,5,0" Click="CloseMainWindow"/>
</Grid>
</Border>
<Border Grid.Row="1" Background="#FF383838">
<TextBlock x:Name="TextBlock" TextWrapping="Wrap" Text="You can see this, when the check box is activated." FontFamily="Segoe UI Light" FontSize="18.667" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="Silver"/>
</Border>
</Grid>
</Window>
您需要注意的方面如下:
DataStateBehavior
响应它的附加(这是 Blend SDK 的一部分)来完成的。当状态改变时,这种行为确保激活相应的视觉状态,即未选中复选框时为“正常”,选中时为“扩展”。WindowStyle
设置为且None
设置ResizeMode
为NoResize
。这可确保窗口周围不显示边框。也可以选择设置AllowTransparency
为,true
但我不建议这样做,因为这会对性能产生一些严重影响。请注意,默认的最小化、最大化/恢复和退出按钮也不会出现在此模式中。如果您还有其他问题,请随时询问。