Different WPF Storyboard Animation in each ListBox.ItemTemplate>DataTemplate - c#

I want to have different animations for each of a ListView item.
<Window.Resources>
<Storyboard x:Key="myAnimation" RepeatBehavior="Forever">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Source" Duration="0:0:2">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="/img/image1.png"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:1">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="/img/image2.png"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<ListBox Name="SessionList" HorizontalContentAlignment="Stretch" >
<ListBox.ItemTemplate>
<DataTemplate>
<Image x:Name="stateimage">
<Image.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard Storyboard="{StaticResource myAnimation}">
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The above XAML code works fine for showing the same animation myAnimation for each listitem. But how I can achive it to show different animations (i.e. I have to define several Storyboards in Window.Resources), depending on a Binding Property of the listitem ViewModel?
EDIT:
With the question linked below, I finally got it worked this way. Amazing!
<Window.Resources>
<Storyboard x:Key="animLOAD" RepeatBehavior="Forever">...</Storyboard>
<Storyboard x:Key="animPREPARED" RepeatBehavior="Forever">...</Storyboard>
<Style x:Key="animStyle" TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=st, Mode=OneWay}" Value="LOAD">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource animLOAD}" />
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding Path=st, Mode=OneWay}" Value="PREPARED">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource animPREPARED}" />
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Image Style="{StaticResource animStyle}" />

I'm not sure how accessible your model is for this approach but you should be able to use it to some measure.
You can use a set of DataTriggers, each inheriting a storyboard:
<DataTrigger Binding="{Binding Property}" Value="SomeValue">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Storyboard}"/>
</DataTrigger.EnterActions>
</DataTrigger>
I would use them within a ControlTemplate:
<ControlTemplate TargetType="Image">
<ControlTemplate.Triggers>
<!-- DataTriggers -->
</ControlTemplate.Triggers>
</ControlTemplate>
EDIT:
This Question has a similar solution, you may not need the ControlTemplate at all.

Related

WPF Listbox Animation on item selected

I'd like to achive this on my wpf app :
when the item is selected, the item moove up and let space for items in this item
and when another item is selected chapter one for example : chapter 2 and 3 shlould be sticked together and chapter one moove up to let space for items in champter one.
edit :
i tried this :
<ListBox x:Name="liste" HorizontalAlignment="Left" Height="274" Margin="10,136,0,0" VerticalAlignment="Top" Width="774">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander Expanded="exp_Expanded" x:Name="exp"></Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform x:Name="transform"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="Selected">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="Margin" BeginTime="00:00:00">
<SplineThicknessKeyFrame KeyTime="00:00:1" Value="0,0,0,100" />
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Could you help me to make this animation please ?
Thanks
1. Create ListboxItem template
2. Set the height of the area to be shown when selected to zero.
3. Adjust the height value through DoubleAnimation in the trigger.
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Width" Value="400"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border x:Name="header">
<TextBlock Text="{Binding Header}" Padding="5 10 0 10"/>
</Border>
<Grid x:Name="items" Grid.Row="1" Height="0" Opacity="0">
<CheckBox Content="{Binding SubItem}" VerticalAlignment="Center" Foreground="White" Margin="10 0 0 0"/>
</Grid>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="items" Storyboard.TargetProperty="Height" To="30" BeginTime="0:0:0.2" Duration="0:0:0.3" />
<DoubleAnimation Storyboard.TargetName="items" Storyboard.TargetProperty="Opacity" To="1" BeginTime="0:0:0.2" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="items" Storyboard.TargetProperty="Height" To="0" Duration="0:0:0.3" />
<DoubleAnimation Storyboard.TargetName="items" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
<Setter Property="Foreground" Value="SkyBlue"/>
<Setter TargetName="header" Property="Background" Value="#132E47"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I put the sample code on github.
👉 here

How can i use isPressed in Label?

this is part of my code, i already search it on google but no one know what i mean.
<Label HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Width="30" Height="30" Content="" FontFamily="FontAwesome" HorizontalAlignment="Right" VerticalAlignment="Center">
<Label.Style>
<Style TargetType="{x:Type Label}">
<Style.Triggers>
<Trigger Property="Label.IsMouseOver" Value="True">
<Setter Property="Label.Background" Value="Yellow" />
</Trigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
You can try using EventTrigger in this case. If's of course longer but it's the simplest approach using pure standard XAML (not any custom):
<Label HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
Width="30" Height="30" Content="Clgt?" FontFamily="FontAwesome"
HorizontalAlignment="Right" VerticalAlignment="Center">
<Label.Style>
<Style TargetType="{x:Type Label}">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseLeftButtonDown">
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="Yellow" Duration="0"
Storyboard.TargetProperty="Background.Color"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeftButtonUp">
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="Transparent" Duration="0"
Storyboard.TargetProperty="Background.Color"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
It's even better to use RemoveStoryboard action when the MouseLeftButtonUp like this:
<Style.Triggers>
<EventTrigger RoutedEvent="MouseLeftButtonDown">
<BeginStoryboard Name="bg">
<Storyboard>
<ColorAnimation To="Yellow" Duration="0"
Storyboard.TargetProperty="Background.Color"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeftButtonUp">
<RemoveStoryboard BeginStoryboardName="bg"/>
</EventTrigger>
</Style.Triggers>

In WPF, how to do when EventTrigger Source is outside a page's resources but Storyboard.TargetName is in a treeview datatemplate?

I have a TreeView whose <ItemTemplate> is defined in HierarchicalDataTemplate
<HierarchicalDataTemplate ItemsSource="{Binding}"
x:Key="TreeTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Name="TextBlockProperty" Text="{Binding Name}" Width="110" Foreground="#FF3C3C3C" >
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding ModifyType}" Value="AutoDetect">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="LightGreen"></SolidColorBrush>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ModifyType}" Value="Prerequisite">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="LightSkyBlue"></SolidColorBrush>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ModifyType}" Value="AutoCheckFailed">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="Red"></SolidColorBrush>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<ContentControl Name="ContentCtrl" Content="{Binding}">
</ContentControl>
</StackPanel>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding ControlType}" Value="Text">
<Setter TargetName="ContentCtrl" Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBox Width="130" Text="{Binding Value}" BorderThickness="0" Background="#FFF8F8F8"></TextBox>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ControlType}" Value="Choice">
<Setter TargetName="ContentCtrl" Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<ComboBox Width="130" IsEditable="True" ItemsSource="{Binding ChoiceItems}" Text="{Binding Value}" BorderThickness="0" >
</ComboBox>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ControlType}" Value="Group">
<Setter TargetName="ContentCtrl" Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock></TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
I have also defined 2 <Buttons> ShowDefault and HideDefault outside the <Page.Resources> to shorten/widen the width of the TextBlockProperty <TextBlock> in the <HierarchicalDataTemplate> by using Storyboard. But I don't know how to do it.
Because it is a TreeView, the Items are actually several columns and rows, more like a form, binded in the <HierarchicalDataTemplate>. But the 2 Buttons are defined in a Grid outside the <Page.Resources>...In order to do the Width shortening/widening, I use Storyboard in <Page.Resources>.
<Storyboard x:Key="ShowDefault">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Width" Storyboard.TargetName="GroupList">
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Width" Storyboard.TargetName="PropertyTree">
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="270"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Width" Storyboard.TargetName="DefaultTree">
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="182"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="HideDefault">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Width" Storyboard.TargetName="GroupList">
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="152"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Width" Storyboard.TargetName="PropertyTree">
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="299"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Width" Storyboard.TargetName="DefaultTree">
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
And call the Storyboard like this:
<Page.Triggers>
<EventTrigger RoutedEvent="ButtonBase.Click" SourceName="ShowDefaultValue">
<BeginStoryboard Storyboard="{StaticResource ShowDefault}"/>
</EventTrigger>
<EventTrigger RoutedEvent="ButtonBase.Click" SourceName="HideDefaultValue">
<BeginStoryboard Storyboard="{StaticResource HideDefault}"/>
</EventTrigger>
</Page.Triggers>
A little complicated, but hope you get it right.
Any help or suggestions will be appreciated. :)
I'm not sure what are you trying to achieve, so I must guess what you meant :).
To get the reference to the TextBlock you can attached to its Loaded event like this:
<TextBlock Loaded="TextBoxLoaded"></TextBlock>
private TextBlock _textBlock;
private void TextBoxLoaded(object sender, RoutedEventArgs e)
{
_textBlock = sender as TextBlock;
}
and then when the button is clicked, changed the properties of the TextBlock.
Normally, the button should be in the template as well for each item of your child template.
OK, I eventually solve the problem by adding a <ScrollView> outside the <StackPanel> of two <TreeView>s. No need to change the DataBinding or anything else.

WPF - DataTrigger animation doesn't work

So I'm trying to make some animations during item removal from ItemsControl which is attached to ObservableCollectio<Item>
I know I can't do this in unload event because it's simply too late to perform any animation so I've tried to do this using DataTrigger
My xaml file looks like this:
<DataTemplate DataType="{x:Type MyApp:Item}">
<Border x:Name="ItemBorder">
<Label Content="{Binding Path=Name}" />
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=Removing}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:1" From="1.0" To="0.0"
Storyboard.TargetProperty="(Border.Opacity)" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
and my Item class is simply:
public class Item : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private bool removing;
public bool Removing {
get
{
return removing;
}
set
{
removing = value;
PropertyChanged(this, new PropertyChangedEventArgs("Removing"));
}
}
// same with `Name` property
}
I would like to start an animation by setting item.Removing = true but nothing happens.
What am I doing wrong?
You will have to update your animation as below i.e give elementname:
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Removing}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:1" From="1.0" To="0.0"
Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ItemBorder" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</DataTemplate.Triggers>
OR
Try putting animation directly on your border style like below:
<DataTemplate DataType="{x:Type MyApp:Item}">
<Border x:Name="ItemBorder">
<Label Content="{Binding Path=Name}" />
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Removing}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:1" From="1.0" To="0.0"
Storyboard.TargetProperty="Opacity" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<Style.Triggers>
</Style>
</DataTemplate>

Change WPF DataGrid cell Background color on CellEditEnding

I have WPF DataGrid and a event handler CellEditEnding, I want a simple code to change the background color of edited cell inside the event handler.
The code below makes a cell bold when successfully edited.
Style
<Style TargetType="Controls:DataGridCell"
BasedOn="{StaticResource {x:Type Controls:DataGridCell}}"
x:Key="CellBoldStyle">
<Style.Triggers>
<EventTrigger RoutedEvent="Binding.SourceUpdated">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames
Duration="00:00:00.5" Storyboard.TargetProperty
="(TextBlock.FontWeight)">
<DiscreteObjectKeyFrame KeyTime="00:00:00"
Value="{x:Static FontWeights.Normal}" />
<DiscreteObjectKeyFrame KeyTime="00:00:00.5"
Value="{x:Static FontWeights.Bold}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
Column
<Controls:DataGridTextColumn
Binding="{Binding Side, Mode=TwoWay,
NotifyOnTargetUpdated=True,
NotifyOnSourceUpdated=True}"
CellStyle="{StaticResource CellBoldStyle}" />

Categories

Resources