I have a ListView whose ItemTemplate is a custom control (acts as expander) that has a toggle that is always visible and border content bellow that expands as needed.
<ControlTemplate TargetType="local:ExpanderControl">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ExpandStateGroup">
<VisualState x:Name="Collapsed">
<!--<Storyboard>
<DoubleAnimation Storyboard.TargetName="PART_ExpandableContent"
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
To="0.0"
Duration="0:0:0.2"
AutoReverse="False"
EnableDependentAnimation="True"></DoubleAnimation>
</Storyboard>
</VisualState>
<VisualState x:Name="Expanded">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="PART_ExpandableContent"
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
To="1.0"
Duration="0:0:0.2"
AutoReverse="False"
EnableDependentAnimation="True"></DoubleAnimation>
</Storyboard>-->
<Storyboard>
<DoubleAnimation Storyboard.TargetName="PART_ExpandableContent"
Storyboard.TargetProperty="Height"
To="0.0"
Duration="0:0:0.2"
AutoReverse="False"
EnableDependentAnimation="True"></DoubleAnimation>
</Storyboard>
</VisualState>
<VisualState x:Name="Expanded">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="PART_ExpandableContent"
Storyboard.TargetProperty="Height"
To="100.0"
Duration="0:0:0.2"
AutoReverse="False"
EnableDependentAnimation="True"></DoubleAnimation>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ToggleButton x:Name="PART_expanderButton" Foreground="{TemplateBinding Foreground}"
Style="{StaticResource ExpanderButtonStyle}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsExpanded , Mode=TwoWay}">
<ContentPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
ContentTemplate="{TemplateBinding HeaderContentTemplate}" Content="{TemplateBinding Header}"
Foreground="{TemplateBinding Foreground}" FontSize="{TemplateBinding FontSize}"
FontWeight="{TemplateBinding FontWeight}" FontStyle="{TemplateBinding FontStyle}"
Margin="{TemplateBinding Padding}"/>
</ToggleButton>
<Border Grid.Row="1" x:Name="PART_ExpandableContent" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
Height="0">
<!--<Border.RenderTransform>
<ScaleTransform ScaleY="0.0" />
</Border.RenderTransform>-->
<ContentPresenter x:Name="PART_ExpandableContentPresenter" Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}">
</ContentPresenter>
</Border>
</Grid>
</ControlTemplate>
I've been playing around with VisualState trying to achieve a simple animation: when clicked the item expands and when clicked again it collapses.
Using Visibility on the "expandable" control would be an option except I want a "growing" animation, having the Height increase until it's full height, instead of the snapping effect that the Visibility provides.
I also messed around with the ScaleY effect and it is almost what I want, except the parent reserves the Height for the expandable control even when this is with ScaleY = 0 leaving a big unwanted space between every element on the list and it makes sense.
Now the working solution as demonstrated above is having a set Height value on the control and varying between this one and 0. But I would like to achieve a more reusable solution without having to hardcode the height.
Any help would be appreciated. Thanks!
Ive recently built a Custom Control that does something similar to the behaviour you are after. Here is a test version to show what I mean as you maybe able to adapt for your project.
Two key points are the control the items you wish to move are in a
StackPanel
and the Height property is manipulated rather than usingTransform.ScaleY
MainPage.xaml
MainPage.xaml.cs
OpenCloseAnimation.cs
Hope it might help