我認爲最簡單的方法是在窗口類中使用自定義視覺狀態。我做了一個小測試項目,你可以在這裏下載: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>
你必須要注意的方面如下:
- 主窗口由一個網格,其第二排是默認隱藏的。這是通過將窗口高度設置爲300而網格實際使用400個邏輯單元來實現的。也可以在運行期間動態計算此高度,但對於此簡單示例,這不是必需的。
- 當「擴展」視覺狀態激活時,第二行變爲可見。這實際上是通過更新相應視圖模型的複選框以及附加的
DataStateBehavior
(這是Blend SDK的一部分)對其作出響應來完成的。當狀態改變時,這種行爲確保相應的視覺狀態被激活,即當複選框未被選中時爲「正常」,當被選中時爲「擴展」。
WindowStyle
設置爲None
,而ResizeMode
設置爲NoResize
。這確保窗口周圍不顯示邊框。也可以選擇將AllowTransparency
設置爲true
,但我不建議這樣做,因爲這有一些嚴重的性能影響。請注意,默認最小化,最大化/恢復和退出按鈕也不會出現在這個工作方式中。
請隨時詢問您是否還有其他問題。
這正是我想要的。謝謝!!! – user1416197 2013-04-29 06:34:48
現在有點複雜了。想象一下,在轉換之前,我不知道最終的(SizeToContent之後的)窗口大小,因爲它取決於加載的數據。 「這是通過將窗口高度設置爲300,而網格實際使用400個邏輯單元來實現的,也可以在運行時動態計算此高度,但對於這個簡單的示例,這不是必需的」我如何在運行時計算這個高度? – user1416197 2013-05-27 19:29:57
解決方法之一是重寫'MainWindow.MeasureOverride'方法。在它中,只需執行下面這行代碼:var size = base.MeasureOverride(availableSize);'和voilà,就可以得到你想要的大小。在這種情況下,我不會推薦使用視覺狀態來創建故事板,而是在代碼中創建它們,然後啓動它們。您可以閱讀有關度量的更多信息,並安排MSDN上的WPF佈局系統的傳遞(http://msdn.microsoft.com/zh-cn/library/ms745058.aspx#LayoutSystem_Measure_Arrange)。 – feO2x 2013-05-29 18:27:01