I'm finding WPF inscrutable at times. Given the following XAML how would one add triggers to animate (slide down, fade in) new items added to the ObservableCollection Timeline. I've seen various examples for list boxes but nothing for items control.
<Grid>
<ScrollViewer>
<ItemsControl Name="TimelineItem"
ItemsSource="{Binding Timeline}"
Style="{StaticResource TimelineStyle}"
ItemContainerStyle="{StaticResource TweetItemStyle}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid VerticalAlignment="Top"
HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Style="{StaticResource TweetImageColumnStyle}" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Rectangle Grid.Column="0"
Style="{StaticResource TweetImageStyle}">
<Rectangle.Fill>
<ImageBrush ImageSource="{Binding ProfileImageUrl}" />
</Rectangle.Fill>
</Rectangle>
<StackPanel Grid.Column="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Style="{StaticResource TweetNameStyle}"
Text="{Binding Name}" />
<TextBlock Grid.Column="1"
Style="{StaticResource TweetTimeStyle}"
Text="{Binding TimeAgo}" />
</Grid>
<Controls:TextBlockMarkup Grid.Row="1"
Grid.Column="1"
Markup="{Binding MarkupText}"
Style="{StaticResource TweetStyle}" />
</StackPanel>
<Separator Grid.Row="2"
Grid.ColumnSpan="2"
Style="{StaticResource TweetSeparatorTop}" />
<Separator Grid.Row="3"
Grid.ColumnSpan="2"
Style="{StaticResource TweetSeparatorBottom}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
It's been a while since I've animated WPF, but this should work by setting a DataTrigger
in the DataTemplate
of the ItemsControl
for the Loaded Event.
A couple of notes:
<Grid>
inside the DataTemplate: "MyGrid"<Grid x:Name="MyGrid" RenderTransformOrigin="0.5,0">
Grid.RenderTransform
attached property to your grid (see sample below)Xaml
<DataTemplate.Resources>
<Storyboard x:Key="ItemAnimation" AutoReverse="False">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MyGrid" Storyboard.TargetProperty="(UIElement.Opacity)">
<EasingDoubleKeyFrame KeyTime="0" Value="0" />
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MyGrid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0" Value="0" />
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</DataTemplate.Resources>
<DataTemplate.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource ItemAnimation}" />
</EventTrigger>
</DataTemplate.Triggers>
Add the RenderTransform groups to your Grid
<!-- Include in the Grid -->
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform/>
</TransformGroup>
</Grid.RenderTransform>
This should get you close enough so that you can customize it yourself. FWIW: I used Blend to build out the animation by editing the style of the ItemTemplate
of the Timeline
object.
One last note: The animation will occur when the window loads the ItemsControl for the first time, for each item in the original collection. And will occur for an individual item when it is added to the collection. This behavior is a bit wonky, so you could remove the explicit binding of the trigger in the xaml and bind the trigger in the code-behind after the ItemsControl or Window loads.
EDIT
RenderTransformOrigin
property.Grid.RenderTransform
attached property.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With