WPF - Animating a change in orientation of a stackpanel? WPF - Animating a change in orientation of a stackpanel? wpf wpf

WPF - Animating a change in orientation of a stackpanel?


There is a feature in Blend called FluidLayout that can do this.

In Blend

  • Create a new state group, set a transition duration and enable fluid layout.
  • Create two states one for horizontal, one for vertical.
  • You can then use a behaviour to toggle between them.

If you don't have Blend you can download the SDK which should have the required files Microsoft.Expression.Interactions and System.Windows.Interactivity. Add references to these and try the sample below.

<Window    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:il="clr-namespace:Microsoft.Expression.Interactivity.Layout;assembly=Microsoft.Expression.Interactions"    xmlns:ic="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"    x:Class="WpfApplication4.MainWindow"    x:Name="Window"    Title="MainWindow"    Width="640" Height="480">    <Grid x:Name="LayoutRoot">        <VisualStateManager.CustomVisualStateManager>            <ic:ExtendedVisualStateManager/>        </VisualStateManager.CustomVisualStateManager>        <VisualStateManager.VisualStateGroups>            <VisualStateGroup x:Name="Orientation" ic:ExtendedVisualStateManager.UseFluidLayout="True">                <VisualStateGroup.Transitions>                    <VisualTransition GeneratedDuration="00:00:00.3000000"/>                </VisualStateGroup.Transitions>                <VisualState x:Name="Vertical"/>                <VisualState x:Name="Horizontal">                    <Storyboard>                        <ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="stack" Storyboard.TargetProperty="(StackPanel.Orientation)">                            <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Orientation.Horizontal}"/>                        </ObjectAnimationUsingKeyFrames>                    </Storyboard>                </VisualState>            </VisualStateGroup>        </VisualStateManager.VisualStateGroups>        <StackPanel x:Name="stack" Margin="8,49,8,8">            <Button Content="Button"/>            <Button Content="Button"/>            <Button Content="Button"/>            <Button Content="Button"/>            <Button Content="Button"/>        </StackPanel>        <Button HorizontalAlignment="Left" Margin="8,8,0,0" VerticalAlignment="Top" Width="97" Height="25" Content="H">            <i:Interaction.Triggers>                <i:EventTrigger EventName="Click">                    <ic:GoToStateAction StateName="Horizontal"/>                </i:EventTrigger>            </i:Interaction.Triggers>        </Button>        <Button HorizontalAlignment="Left" Margin="109,8,0,0" VerticalAlignment="Top" Width="97" Height="25" Content="V">            <i:Interaction.Triggers>                <i:EventTrigger EventName="Click">                    <ic:GoToStateAction StateName="Vertical"/>                </i:EventTrigger>            </i:Interaction.Triggers>        </Button>    </Grid></Window>

You can use a similar method to handle the item transition using states to move the elements or by changing Grid.Row,RowSpan,Col. You may need some code to tie everything together. I'm looking at a more elaborate sample I'll post if I sort out the issues.