I want the items added to my ItemsControl to animate the height when they're added. The following sample, using triggers, did the job, but I couldn't get it to work with a non-fixed height for the items (50 in this case).
<ItemsControl ItemsSource="{Binding Notifications}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type Notifications1:Notification}">
<Button x:Name="ItemButton"
ClipToBounds="True"
Height="0">
<Button.Template>
<ControlTemplate>
<Notifications:NotificationTile />
</ControlTemplate>
</Button.Template>
</Button>
<DataTemplate.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded"
SourceName="ItemButton">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Height"
Storyboard.TargetName="ItemButton"
Duration="0:0:0.5"
To="50" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.Resources>
I then tried to use the VisualStateManager to perform the animations, so the tiles would grow to whatever height they required. In the example below, the items are added at the correct size, but no animation is performed. I assume the EventTrigger isn't even being fired?
Any ideas much appreciated!
<ItemsControl ItemsSource="{Binding Notifications}"
Width="230"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
HorizontalContentAlignment="Stretch">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type Notifications1:Notification}">
<Button x:Name="ItemButton"
ClipToBounds="True"
Command="{Binding DataContext.ItemClicked, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
CommandParameter="{Binding}"
Visibility="{Binding IsVisible, Converter={StaticResource boolToVisibilityConverter}}">
<Button.Template>
<ControlTemplate>
<Notifications:NotificationTile />
</ControlTemplate>
</Button.Template>
<VisualStateManager.CustomVisualStateManager>
<is:ExtendedVisualStateManager />
</VisualStateManager.CustomVisualStateManager>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup is:ExtendedVisualStateManager.UseFluidLayout="True">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:2" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Collapsed">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(FrameworkElement.Height)"
Storyboard.TargetName="ItemButton"
Duration="0"
To="0" />
</Storyboard>
</VisualState>
<VisualState x:Name="Expanded">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)"
Storyboard.TargetName="ItemButton">
<DiscreteDoubleKeyFrame KeyTime="0"
Value="NaN" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<i:Interaction.Triggers>
<i:EventTrigger SourceName="ItemButton"
EventName="(FrameworkElement.Loaded)">
<is:GoToStateAction StateName="Expanded" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</DataTemplate>
</ItemsControl.Resources>
Maybe this is a bit off-topic, sorry for that. I'm not sure I understood your question fully.
Anyway, it generally cannot be recommended to have an animation with only "To", as the "From" is originally set to a Double.NaN, and the DoubleAnimation doesn't work in this case.
Related
After looking at several examples on this site it appears that the type of animation I wanted here is not that hard. Right now I've this in my xaml:
<ItemsControl ItemsSource="{Binding MyCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Name="Info">
<TextBlock Text="{Binding ItemName}"/>
<TextBlock Text="{Binding Quantity}"/>
<TextBlock Text="{Binding Price}"/>
</StackPanel>
<DataTemplate.Resources>
<Storyboard x:Key="Anim">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Info"
Storyboard.TargetProperty="(UIElement.Opacity)">
<EasingDoubleKeyFrame KeyTime="0" Value="0" />
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</DataTemplate.Resources>
<DataTemplate.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard Storyboard="{StaticResource Anim}" />
</EventTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
an in code, I'm adding last item in first place in this way:
MyCollection.Insert(0, new Transaction()
{
Name = ItemName + " ",
Quantity = QuantityTraded,
Price = AtPrice
});
With all these new item fades in on the left corner and pushes all existing items to the right BUT the behavior is snappy! I want a translate instead of opacity and for that I've to have this in StackPanel inside DataTemplate:
<StackPanel.RenderTransform>
<TransformGroup>
<TranslateTransform/>
</TransformGroup>
</StackPanel.RenderTransform>
What do I have to have in Storyboard for TranslateTransform?
Will it animate all existing items or those will snap to their target position as they do with these code?
I've tried with blend which inserted these:
<b:Interaction.Behaviors>
<b:FluidMoveBehavior Duration="0:0:5" AppliesTo="Children">
<b:FluidMoveBehavior.EaseY>
<BackEase EasingMode="EaseOut"/>
</b:FluidMoveBehavior.EaseY>
<b:FluidMoveBehavior.EaseX>
<BackEase EasingMode="EaseIn"/>
</b:FluidMoveBehavior.EaseX>
</b:FluidMoveBehavior>
</b:Interaction.Behaviors>
inside ItemsControl but that didn't change the behavior!
As a starting point, you could animate the Width property of the StackPanel from 0 to its maximum width. This will indeed push all items to the right as the first item grows.
<Storyboard x:Key="Anim">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Info"
Storyboard.TargetProperty="Width">
<EasingDoubleKeyFrame KeyTime="0" Value="0" />
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="100" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
But animating the Width might not be the visual effect you intend.
You could elaborate on that and instead animate the Width of an outer element that will crop your inner StackPanel:
<DataTemplate>
<StackPanel x:Name="Outer" Margin="5">
<StackPanel x:Name="Info" Orientation="Vertical" HorizontalAlignment="Right" Width="50">
<TextBlock Text="{Binding ItemName}"/>
<TextBlock Text="{Binding Quantity}"/>
<TextBlock Text="{Binding Price}"/>
</StackPanel>
</StackPanel>
<DataTemplate.Resources>
<Storyboard x:Key="Anim">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Outer"
Storyboard.TargetProperty="Width">
<EasingDoubleKeyFrame KeyTime="0" Value="0" />
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="50" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</DataTemplate.Resources>
<DataTemplate.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard Storyboard="{StaticResource Anim}" />
</EventTrigger>
</DataTemplate.Triggers>
</DataTemplate>
You might have to do some adjustments from here to remove any hardcoded values in the animations.
I have <ItemsControl> which create view for my <custom:Pack> list:
<ItemsControl ItemsSource="{Binding List}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<local:ShelfPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="local:ShelfPanel.Exact" Value="{Binding Exact}"/>
// Default ZIndex is set 1, when Active it should be higher, hence will be over others.
<Setter Property="Panel.ZIndex" Value="1" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<custom:Pack Background="Red" Width="150" Height="150" >
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MyStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)" To="Yellow" Duration="0:0:0.5" />
</Storyboard>
</VisualState>
<VisualState x:Name="Active">
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)" To="Green" Duration="0:0:0.5" />
// How to animate ZIndex on ContentPresenter ?
<Int32Animation Storyboard.TargetProperty="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ContentPresenter}}, Path=(Panel.ZIndex)}" To="3" Duration="00:00:0.2"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</custom:Pack>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The <local:ShelfPanel> is designed that way <custom:Pack> is overlapping each other. Now when you select one <custom:Pack> it's state change to Active and object should be over all others.
Currenty I get expection:
You must specify TargetProperty for "System.Windows.Media.Animation.Int32 Animation
To achive this I need set ZInedx on ContentPresenter, how to do it?
I have stack panel in hyperlink button on button click i have to change stack panel background
<HyperlinkButton Name="WhereToStayButton" Margin="0,0,0,0" Grid.Row="5" Click="WhereToStayButton_Click">
<HyperlinkButton.Template>
<ControlTemplate TargetType="HyperlinkButton">
<StackPanel Orientation="Horizontal" Background="#EBEBEB" x:Name="sp1">
<Image Source="/Assets/Menu/wheretostay.png" Stretch="None"/>
<TextBlock Text="{Binding Path=LocalizedResources.menu_where_stay, Source={StaticResource LocalizedStrings}}" VerticalAlignment="Center" Margin="5,10" FontSize="26" Foreground="Black" FontFamily="{StaticResource CustomLucidaGrandStyle}"/>
</StackPanel>
</ControlTemplate>
</HyperlinkButton.Template>
</HyperlinkButton>
Try this
use this name space using System.Windows.Media; and in button click event write this
private void WhereToStayButton_Click(object sender, RoutedEventArgs e)
{
stackpanelname.Background = new SolidColorBrush(Colors.Red);
}
You can do that by applying Storyboard on Click event trigger:
<ControlTemplate TargetType="HyperlinkButton">
<StackPanel Orientation="Horizontal" Background="#EBEBEB" x:Name="sp1">
<Image Source="/Assets/Menu/wheretostay.png" Stretch="None"/>
<TextBlock />
</StackPanel>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="ButtonBase.Click">
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="Green" Storyboard.TargetName="sp1"
Storyboard.TargetProperty="Background.Color"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
For Windows Phone 7, use Visual State:
<ControlTemplate TargetType="HyperlinkButton">
<ControlTemplate.Resources>
<SolidColorBrush x:Key="PhoneBackgrounBrush" Color="Green"/>
</ControlTemplate.Resources>
<StackPanel Orientation="Horizontal" x:Name="sp1">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty="Background"
Storyboard.TargetName="sp1">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource PhoneBackgrounBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Image Source="/Assets/Menu/wheretostay.png" Stretch="None"/>
<TextBlock />
</StackPanel>
</ControlTemplate>
As Rohit said, Make use of Visual states to achive your requirement..,
<ControlTemplate TargetType="HyperlinkButton">
<StackPanel Orientation="Horizontal" Background="#EBEBEB" x:Name="sp1">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="sp1">
<EasingColorKeyFrame KeyTime="0" Value="#FFE91818"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Image Source="/Assets/Menu/wheretostay.png" Stretch="None"/>
<TextBlock />
</StackPanel>
</ControlTemplate>
I'm trying to change the height of a WPF grid from 0 to Auto using Storyboard. I know I can't do it without tricking, so I tried to change the MaxHeight Value, using Databinding in the Storyboard. But I can't make it works (height is always equals to 0). Here is the code I use :
The two visualstates :
<VisualState x:Name="SelectionMode">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="CurrentToolGrid" Storyboard.TargetProperty="(FrameworkElement.MaxHeight)">
<EasingDoubleKeyFrame KeyTime="0" Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="EditionMode">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="CurrentToolGrid" Storyboard.TargetProperty="(FrameworkElement.MaxHeight)">
<EasingDoubleKeyFrame KeyTime="0" Value="{Binding ElementName=CurrentToolGrid, Path=ActualHeight}" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
Here is my grid definition :
<Grid x:Name="CurrentToolGrid" Background="#FFDEDEDE" Grid.Row="1" Height="Auto">
[... some controls that extends the grid's height ...]
</Grid>
Why the height of the CurrentToolGrid is always 0 ?
Thanks for helping me :)
Please refer to following code, I use TranslateTransform instead of MaxWidth, it make scense for Slide scenario.The key to impl this is StoryBoard should define in resource, then storyboard can find the specify control which binding in doubleanimation.
<Window x:Class="SlideUpWPFTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
x:Name="Window"
Title="MainWindow"
Width="640"
Height="480">
<Window.Resources>
<Storyboard x:Key="sb1">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="grdContent" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<EasingDoubleKeyFrame KeyTime="0" Value="{Binding ElementName=grdContent, Path=ActualWidth}" />
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="sb2">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="grdContent" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<EasingDoubleKeyFrame KeyTime="0" Value="0" />
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="{Binding ElementName=grdContent, Path=ActualWidth}" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Grid x:Name="LayoutRoot" RenderTransformOrigin="0.5,0.5">
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</Grid.RenderTransform>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualState x:Name="EditMode" Storyboard="{StaticResource sb1}" />
<VisualState x:Name="SelectionMode" Storyboard="{StaticResource sb2}" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button Content="Enter Edit Mode">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:GoToStateAction StateName="EditMode" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Button Content="Enter Selected Mode">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:GoToStateAction StateName="SelectionMode" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</StackPanel>
<Grid x:Name="grdContent"
Grid.Row="1"
RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</Grid.RenderTransform>
<!-- some content -->
<Rectangle Height="65" Fill="LightBlue" />
</Grid>
</Grid>
</Window>
I am trying to use a DataTemplate for ListBox.ItemTemplate for a simple TODO list.
The template for each ListBoxItem is a grid and I want the content for my 2nd column to stretch the remaining width of the listbox. No amount of HorizontalAlignment="Stretch" etc. etc. seems to do the trick and I think I need to modify the template. I've looked at the ListBox extracted Xaml template but cannot see what I need to change.
In this XAML sample you can see a green box that is supposed to stretch the remaining width of the listboxitem, but doesn't.
In XamlPad / WPF this code actually DOES render as expected.
In Silverlight though the box won't stretch.
<ListBox Width="360" Height="150" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="3,0,3,0" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="URGENT" Foreground="Red" Margin="5,0,10,0" Grid.Column="0" VerticalAlignment="Center"/>
<Border BorderBrush="Green" BorderThickness="1" Grid.Column="1" HorizontalAlignment="Stretch" Margin="0,2">
<TextBlock Margin="5,2" Text="{Binding}" FontWeight="Bold" />
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<s:String>Take out trash</s:String>
<s:String>Clean car</s:String>
<s:String>Finish TODO list program</s:String>
<s:String>Sleep</s:String>
</ListBox>
You can achieve what you want by defining a ItemContainerStyle for your ListBox :
<Style x:Key="ListBoxItemStyle1" TargetType="ListBoxItem">
<Setter Property="Padding" Value="3"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Duration="0" To=".35" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="fillColor"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" To=".55" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="contentPresenter"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected"/>
<VisualState x:Name="Selected">
<Storyboard>
<DoubleAnimation Duration="0" To=".75" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="fillColor2"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="FocusVisualElement">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid HorizontalAlignment="Stretch" Margin="3,0,3,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="URGENT" Foreground="Red" Margin="5,0,10,0" Grid.Column="0" VerticalAlignment="Center"/>
<Border BorderBrush="Green" BorderThickness="1" Grid.Column="1" HorizontalAlignment="Stretch" Margin="0,2">
<TextBlock Margin="5,2" Text="{Binding}" FontWeight="Bold" />
</Border>
</Grid>
<Rectangle x:Name="fillColor" Fill="#FFBADDE9" IsHitTestVisible="False" Opacity="0" RadiusY="1" RadiusX="1"/>
<Rectangle x:Name="fillColor2" Fill="#FFBADDE9" IsHitTestVisible="False" Opacity="0" RadiusY="1" RadiusX="1"/>
<Rectangle x:Name="FocusVisualElement" RadiusY="1" RadiusX="1" Stroke="#FF6DBDD1" StrokeThickness="1" Visibility="Collapsed"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And then use this style in your listbox like this :
<ListBox Width="360" Height="150" x:Name="lb" HorizontalContentAlignment="Stretch" ItemContainerStyle="{StaticResource ListBoxItemStyle1}" />
In what you are trying to do , the problem is your grid width is not equivalent to the listbox item.
The problem is the Grid inside the DataTemplate, if you increase its size, you'll start to see that the border grows with it.