Animate newly added item in Listbox - wpf

I am trying to add animation to newly added item and/or changed item in my listbox, this is what i've done so far:
<Style x:Key="ListBoxItemStyle4" TargetType="{x:Type ListBoxItem}">
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform x:Name="transform" />
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:2" />
<DoubleAnimation Storyboard.TargetProperty="LayoutTransform.ScaleY" From="0" Duration="0:0:.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
This animates every item in my listbox.

There's a working example explained in this article:
https://social.technet.microsoft.com/wiki/contents/articles/31416.wpf-mvvm-friendly-user-notification.aspx#Toast
It applies the animation via itemcontainerstyle:
<ListBox ItemsSource="{Binding Messages}" BorderBrush="Transparent" Background="LightGray">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform/>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:1.2" FillBehavior="Stop" />
<DoubleAnimation Storyboard.TargetProperty="LayoutTransform.ScaleY" From="0" Duration="0:0:1.2" FillBehavior="Stop">
<DoubleAnimation.EasingFunction>
<BounceEase Bounces="2" Bounciness="6"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
Also addressed is animating before removal.

Related

Can this animation not spam?

I am pretty new to xaml and wpf in general, so excuse me if the solution is easy or the xaml i used is bad. I am unsure if this is possible, but if there is some kind of solution please let me know!
Here is a video of what i am trying to fix:
https://imgur.com/a/NmnV50S
If the video doesn't explain my problem, here it is: can the button animation not spam or bug when the user moves his cursor very fast across the button?
Here is the xaml for the animation:
<Style x:Key="SlidingButtonToRight" TargetType="Button">
<Setter Property="Width" Value="270"/>
<Setter Property="Height" Value="80"/>
<Setter Property="UseLayoutRounding" Value="True"/>
<Setter Property="ClipToBounds" Value="True"/>
<Setter Property="FontSize" Value="20"/>
<Setter Property="Button.RenderTransform">
<Setter.Value>
<TranslateTransform/>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border" BorderThickness="0" BorderBrush="Black" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.8" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Image.RenderTransform).(TranslateTransform.X)" From="0" To="110" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Image.RenderTransform).(TranslateTransform.X)" From="110" To="0" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
<Style x:Key="SlidingButtonToLeft" TargetType="Button" BasedOn="{StaticResource SlidingButtonToRight}">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Image.RenderTransform).(TranslateTransform.X)" From="0" To="-110" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Image.RenderTransform).(TranslateTransform.X)" From="-110" To="0" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
Here is the xaml for the button on which i use the animation style:
<Button x:Name="button4" Click="Button4_Click" Style="{DynamicResource SlidingButtonToLeft}" Margin="0,50,-186,0" VerticalAlignment="Top" HorizontalAlignment="Right">
<Button.Background>
<ImageBrush ImageSource="Assets/programm-bt.png"/>
</Button.Background>
<TextBlock Text="Programm" TextAlignment="Left" Width="105" Margin="0,0,-25,0" HorizontalAlignment="Center"/>
</Button>
To reduce the animation spam, you can set a BeginTime property on your MouseLeave animation to give the user enough time to move the mouse off the button before the animation starts.
You can start with .2 seconds and tweak from there:
<Storyboard>
<DoubleAnimation
BeginTime="0:0:0.2"
Storyboard.TargetProperty="(Image.RenderTransform).(TranslateTransform.X)"
From="-110"
To="0"
Duration="0:0:0.3" />
</Storyboard>
I figured it out, by removing From ,the animation doesn't start from 0 every time the user hovers over the button. Here is a video from before and after the change.
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Image.RenderTransform).(TranslateTransform.X)"
To="110"
Duration="0:0:0.2"
/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(Image.RenderTransform).(TranslateTransform.X)"
To="0"
Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>

Why XAML defined animation causes System.InvalidOperationException

I need define simple animation in the XAML (without code behind), that must rotate the background image of button by changing the bounded boolean property. I have a button in the XAML:
<Button Style="{StaticResource btnStyle}" />
In the Resources section of the Window I create following:
<RotateTransform Angle="180" x:Key="rotAt180" />
<Style TargetType="Button" x:Key="btnStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Image Source="Images\pic.png" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding MyBoolProp}" Value="False">
<Setter Property="RenderTransform" Value="{StaticResource rotAt180}" />
<!-- This animation works good -->
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation From="0" To="180" Duration="0:0:0.2" Storyboard.TargetProperty="RenderTransform.Angle" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<!-- This animation causes exception -->
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation From="180" To="0" Duration="0:0:0.2" Storyboard.TargetProperty="RenderTransform.Angle" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
MyBoolProp is initialized by True.
The first animation is works perfect. But the second animation causes System.InvalidOperationException in PresentationFramework.dll ("Unable to resolve all property references in the "RenderTransform.Angle" property path. Check that the corresponding objects support such properties").
I tried to move the second animation into the trigger, where MyBoolProp is True:
<DataTrigger Binding="{Binding MyBoolProp}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation From="180" To="0" Duration="0:0:0.2" Storyboard.TargetProperty="RenderTransform.Angle" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
But the result is the same. What is wrong in such realization?
The RenderTransform must be set in the Style, not in the DataTrigger:
<Style TargetType="Button" x:Key="btnStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Image Source="Images\pic.png" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="RenderTransform" Value="{StaticResource rotAt180}"/>
<Setter Property="RenderTransformOrigin" Value="0.5,0.5" />
<Style.Triggers>
<DataTrigger Binding="{Binding MyBoolProp}" Value="False">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation To="0" Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.Angle" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation To="180" Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.Angle" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>

How can we show WPF button contents on MouseOver with transperent background

i want the WPF button behaves in a way on mouse over only i want to show content of button (its an image)
and also on mouseover i want the background as transparent + no border .
Button content is an image and i am giving a padding of 50 px . so mouse is anywhere near to 50px on button i can see the button content.
The xaml i used is
<Button Style="{StaticResource FadeOutButton}" Padding="50" Opacity="0" >
<Image Source="Images\myimage.JPG"></Image>
and
<Style x:Key="FadeOutButton" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<EventTrigger RoutedEvent="Control.MouseEnter">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Duration="0:0:1" To="1" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Control.MouseLeave">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Duration="0:0:1" To="0" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
What else i have to add to make the background transparent on mouseover in addition to current effect
Try this
<Window.Resources>
<Style x:Key="FadeOutButton" TargetType="{x:Type Button}">
<Style.Resources>
<Storyboard x:Key="MouseOverAnimation" >
<DoubleAnimation Duration="0:0:1" To="1" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
<Storyboard x:Key="MouseOutAnimation">
<DoubleAnimation Duration="0:0:1" To="0" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="Transparent" >
<ContentPresenter Margin="{TemplateBinding Padding}" HorizontalAlignment="Center" Content="{TemplateBinding Content}" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent"/>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource MouseOverAnimation}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource MouseOutAnimation}" />
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Button Style="{StaticResource FadeOutButton}" Padding="50" Opacity="0" >
<Image Source="Screenshot_3.png"></Image>
</Button>

Smoothly resize an UIElement

I have a set of Ellipses on my Canvas.
For the MouseEnter event on each of the ellipses, I would like to resize the element so as to give a magnifying look and feel.
To make it more attractive, I want to make the change gradual (smooth/animated feeling). Any hints are appreciated.
Try something like this:
<Style x:Key="ScaleStyle" TargetType="{x:Type FrameworkElement}">
<Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform />
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation To="1.2" Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleX" />
<DoubleAnimation To="1.2" Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleY" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation To="1.0" Duration="0:0:0.1"
Storyboard.TargetProperty="RenderTransform.ScaleX" />
<DoubleAnimation To="1.0" Duration="0:0:0.1"
Storyboard.TargetProperty="RenderTransform.ScaleY" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Canvas>
<Ellipse Style="{StaticResource ScaleStyle}" Canvas.Left="100" Canvas.Top="100"
Width="200" Height="100" Stroke="Black" StrokeThickness="2" Fill="Transparent" />
</Canvas>

Animating things in WPF - name cannot be found in the name scope of 'System.Windows.Controls.ControlTemplate'

Been trying to make a tabcontrol with some animation when changing tabs but it keeps giving me grief and refusing to let me put the animation in any useful place unless it's in the same XAML window file as the control itself (the style resides in a DLL file from which other styles work). Here's my style:
<Style x:Key="AnimatedTabControl" TargetType="{x:Type TabControl}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Background" Value="White" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border>
<TabPanel
IsItemsHost="True">
</TabPanel>
</Border>
<Border BorderThickness="0"
Grid.Row="1"
BorderBrush="White"
Background="White">
<ContentPresenter x:Name="TabControlContent" ContentSource="SelectedContent" Margin="0" />
</Border>
</Grid>
<ControlTemplate.Resources>
<Storyboard x:Key="TabSelectionChangedStoryboard">
<DoubleAnimation Storyboard.TargetName="TabControlContent"
Storyboard.TargetProperty="Opacity"
To="100"
From="0"
FillBehavior="HoldEnd"
Duration="0:0:30.0" />
</Storyboard>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="SelectionChanged">
<BeginStoryboard Storyboard="{StaticResource TabSelectionChangedStoryboard}" />
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This results in 'TabControlContent' name cannot be found in the name scope of 'System.Windows.Controls.ControlTemplate'
I've also tried to move the animation to the beginning of the file, which results in the same error. If I put it after the style, the storyboard can't find it. Is there any way around this?
Solution:
use Storyboard.Target instead of Storyboard.TargetName in combination with {Binding ElementName=TabControlContent.
replace
<DoubleAnimation
Storyboard.TargetName="TabControlContent"
Storyboard.TargetProperty="Opacity"
To="100"
From="0"
FillBehavior="HoldEnd"
Duration="0:0:30.0" />
with
<DoubleAnimation
Storyboard.Target="{Binding ElementName=TabControlContent}"
Storyboard.TargetProperty="Opacity"
To="100"
From="0"
FillBehavior="HoldEnd"
Duration="0:0:30.0" />
I search on web a lot but did not found appropriate answer... and after four days try Finally completed this way...
<ControlTemplate x:Key="GeneralButton" TargetType="{x:Type Button}">
<Grid>
<Border Background="{StaticResource ButtonGeneral}"
VerticalAlignment="Stretch" CornerRadius="6" HorizontalAlignment="Stretch"/>
<Border x:Name="BorderFocused" Opacity="0" Background="{StaticResource ButtonFocused}"
VerticalAlignment="Stretch" CornerRadius="6" HorizontalAlignment="Stretch"/>
<Border x:Name="BorderPressed" Opacity="0" Background="Purple"
VerticalAlignment="Stretch" CornerRadius="6" HorizontalAlignment="Stretch"/>
<Border x:Name="BorderDisabled" Opacity="0" Background="{StaticResource ButtonDisabled}"
VerticalAlignment="Stretch" CornerRadius="6" HorizontalAlignment="Stretch"/>
<ContentPresenter VerticalAlignment="Center"
HorizontalAlignment="Center" x:Name="MainContent" Margin="20,5" >
<TextElement.Foreground>
<SolidColorBrush Color="White"></SolidColorBrush>
</TextElement.Foreground>
<TextElement.FontSize>
16
</TextElement.FontSize>
</ContentPresenter>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="BorderFocused" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.01"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="BorderFocused" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.4"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="BorderFocused" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.01"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="BorderFocused" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.4"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="BorderPressed" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.01"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="BorderPressed" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.5"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="BorderDisabled" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="BorderDisabled" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
I solved the problem using the "VisualStateManager", at the following link you will find a brief explanation of the differences between "VisualStateManager" and "Triggers".
https://stackoverflow.com/a/41030110/13037386
This shows how the graphic states are detached from triggers.

Resources