Reputation: 25563
I try to implement a ListBox where the selected item is displayed in more detail than the others. One approach is shown by Josh Smith on his blog.
To enhance the user experience, I'd like to animate the change (i.e. the item growing larger, additional information fading in). Using the DataTriggers Enter- or ExitActions to start Storyboard has the disadvandates, that
Is there another approach thats more easily maintainable?
Upvotes: 3
Views: 443
Reputation: 17073
You could use this ListBox.ItemContainerStyle
and adjust it for your needs.
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border>
<StackPanel>
<ContentPresenter x:Name="Compact"
Opacity="1"
ContentTemplate="{StaticResource UnselectedDataTemplate}">
<ContentPresenter.LayoutTransform>
<ScaleTransform ScaleY="1" />
</ContentPresenter.LayoutTransform>
</ContentPresenter>
<ContentPresenter x:Name="Details"
Opacity="0"
ContentTemplate="{StaticResource SelectedDataTemplate}">
<ContentPresenter.LayoutTransform>
<ScaleTransform ScaleY="0" />
</ContentPresenter.LayoutTransform>
</ContentPresenter>
</StackPanel>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="SelectionStates">
<VisualState Name="Unselected">
<Storyboard SpeedRatio="2">
<DoubleAnimation To="1"
Storyboard.TargetName="Compact"
Storyboard.TargetProperty="Opacity" />
<DoubleAnimation To="1"
Storyboard.TargetName="Compact"
Storyboard.TargetProperty="LayoutTransform.(ScaleTransform.ScaleY)" />
<DoubleAnimation To="0"
Storyboard.TargetName="Details"
Storyboard.TargetProperty="Opacity" />
<DoubleAnimation To="0"
Storyboard.TargetName="Details"
Storyboard.TargetProperty="LayoutTransform.(ScaleTransform.ScaleY)" />
</Storyboard>
</VisualState>
<VisualState Name="Selected">
<Storyboard SpeedRatio="2">
<DoubleAnimation To="0"
Storyboard.TargetName="Compact"
Storyboard.TargetProperty="Opacity" />
<DoubleAnimation To="0"
Storyboard.TargetName="Compact"
Storyboard.TargetProperty="LayoutTransform.(ScaleTransform.ScaleY)" />
<DoubleAnimation To="1"
Storyboard.TargetName="Details"
Storyboard.TargetProperty="Opacity" />
<DoubleAnimation To="1"
Storyboard.TargetName="Details"
Storyboard.TargetProperty="LayoutTransform.(ScaleTransform.ScaleY)" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In this case I have declared the templates as resources.
<DataTemplate x:Key="UnselectedDataTemplate">
/* your controls for unselected state */
</DataTemplate>
<DataTemplate x:Key="SelectedDataTemplate">
/* your controls for selected state */
</DataTemplate>
But I think binding datatemplated content directly to ContentPresenter.Content
is possible too.
If Details are additional and not for replacement of Compact, simply remove all DoubleAnimation
from Storyboard
with Storyboard.TargetName="Compact"
.
Hope this helps.
Upvotes: 1