EventTrigger RoutedEvent amimation in wpf xaml - wpf

I want an animation to be launched when MyObject.IsGlowing = true so I did this (I'm in a <DataTemplate> if that can help)
<Ellipse Width="100" Height="100" Name="MyEllipse">
<Ellipse.Fill>
<RadialGradientBrush >
<GradientStop Offset="0" Color="Red" />
<GradientStop Offset="0.5" Color="red" />
<GradientStop Offset="1" Color="red"/>
</RadialGradientBrush >
</Ellipse.Fill>
<Ellipse.Triggers>
<DataTrigger Binding="{Binding Source=IsGlowing}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Name="MyBeginStoryBoard">
<Storyboard Name="MyStoryBoard" >
//Animation
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Ellipse.Triggers>
</Ellipse>
but I got this error "Triggers collection members must be of type EventTrigger" so I changed it to
<Ellipse Width="100" Height="100" Name="MyEllipse">
<Ellipse.Fill>
<RadialGradientBrush >
<GradientStop Offset="0" Color="Red" />
<GradientStop Offset="0.5" Color="red" />
<GradientStop Offset="1" Color="red"/>
</RadialGradientBrush >
</Ellipse.Fill>
<Ellipse.Triggers>
<EventTrigger RoutedEvent="?">
<BeginStoryboard Name="MyBeginStoryBoard">
<Storyboard Name="MyStoryBoard" >
//Animation
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
But i have no idea what to put in RoutedEvent...

You aren't allowed DataTriggers to be directly used/specified within an elements Triggers collection. However, you can use a Style to apply one.
http://www.thejoyofcode.com/Help_Why_cant_I_use_DataTriggers_with_controls_in_WPF.aspx

Related

Unset databound property when animation completes in WPF

I would like to set my databound property IsFlashing to False when my animation completes.
<Border BorderThickness="1"
Height="15"
Width="20"
CornerRadius="2"
BorderBrush="Black"
DockPanel.Dock="Top"
Grid.Row="1" >
<Border.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding IsFlashing}" Value="True" x:Name="dataTrigger">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard FillBehavior="Stop" RepeatBehavior="1x" x:Name="startStoryBoard">
<ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty="Background"
Duration="0:0:4" RepeatBehavior="1x">
<ObjectAnimationUsingKeyFrames.KeyFrames>
<DiscreteObjectKeyFrame KeyTime="0:0:1">
<DiscreteObjectKeyFrame.Value>
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStop Color="Yellow" Offset="0.0" />
<GradientStop Color="Orange" Offset="0.9" />
<GradientStop Color="Red" Offset="1.0" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames.KeyFrames>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<!-- how can I set my bound property "IsFlashing" to false when we exit here ? -->
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FFFFFF" Offset="0.0" />
<GradientStop Color="#ADD8E6" Offset="0.9" />
<GradientStop Color="#8aacb8" Offset="1.0" />
</LinearGradientBrush>
</Border.Background>
<TextBlock Foreground="Black" Text="{Binding Path=MarkerCode}" FontFamily="Segoe UI" FontSize="12" TextAlignment="Center" VerticalAlignment="Center">
<TextBlock.Effect>
<DropShadowEffect ShadowDepth="0" BlurRadius="3" Color="White" />
</TextBlock.Effect>
</TextBlock>
</Border>
Listen to the Completed event of the ObjectAnimationUsingKeyFrames
ExitActions are what happens when the trigger condition is no longer met (in this case when IsFlashing returns to false), which is not the same the animation completing.

WPF simple brush animation causes a performance issue

I've created a simple animation that rotates a linear gradient brush used as a background for an ellipse. I used it on 4 ellipses, and it takes about 6% CPU in average alone. Is there any way I can improve the performance? (Parts of the ellipses are hidden on purpose).
<Window x:Class="MyAnimation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:testDisplayAccessPoints="clr-namespace:TestDisplayAccessPoints"
xmlns:zoomAndPan="clr-namespace:ZoomAndPan;assembly=ZoomAndPan"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
Title="MainWindow" Height="1100"
Width="1100">
<Window.Resources>
<Storyboard x:Key="Storyboard1" RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetProperty="(Shape.Stroke).(Brush.RelativeTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="ellipseLow"
Timeline.DesiredFrameRate="12" From="0" To="359" Duration="0:00:3.0" />
<DoubleAnimation Storyboard.TargetProperty="(Shape.Stroke).(Brush.RelativeTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="ellipseMedium"
Timeline.DesiredFrameRate="12" From="0" To="359" Duration="0:00:3.0" />
<DoubleAnimation Storyboard.TargetProperty="(Shape.Stroke).(Brush.RelativeTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="ellipseHigh"
Timeline.DesiredFrameRate="12" From="0" To="359" Duration="0:00:3.0" />
<DoubleAnimation Storyboard.TargetProperty="(Shape.Stroke).(Brush.RelativeTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="ellipseVeryHigh"
Timeline.DesiredFrameRate="12" From="0" To="359" Duration="0:00:3.0" />
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
</Window.Triggers>
<Grid x:Name="BackgroundGrid" Background="Black">
<Ellipse x:Name="ellipseLow" HorizontalAlignment="Left" Height="800" Margin="-720,0,0,0" StrokeThickness="5" VerticalAlignment="Center" Width="1600">
<Ellipse.Stroke>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<LinearGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform CenterY="0.5" CenterX="0.5"/>
<SkewTransform CenterY="0.5" CenterX="0.5"/>
<RotateTransform Angle="90" CenterY="0.5" CenterX="0.5"/>
<TranslateTransform/>
</TransformGroup>
</LinearGradientBrush.RelativeTransform>
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Gold" Offset="0.2"/>
<GradientStop Color="Gold" Offset="0.8"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Ellipse.Stroke>
</Ellipse>
<Ellipse x:Name="ellipseMedium" HorizontalAlignment="Left" Height="600" Margin="-520,0,0,0" StrokeThickness="5" VerticalAlignment="Center" Width="1200">
<Ellipse.Stroke>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<LinearGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform CenterY="0.5" CenterX="0.5"/>
<SkewTransform CenterY="0.5" CenterX="0.5"/>
<RotateTransform Angle="90" CenterY="0.5" CenterX="0.5"/>
<TranslateTransform/>
</TransformGroup>
</LinearGradientBrush.RelativeTransform>
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Gold" Offset="0.2"/>
<GradientStop Color="Gold" Offset="0.8"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Ellipse.Stroke>
</Ellipse>
<Ellipse x:Name="ellipseHigh" HorizontalAlignment="Left" Height="400" Width="800" Margin="-320,0,0,0" StrokeThickness="5" VerticalAlignment="Center" >
<Ellipse.Stroke>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<LinearGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform CenterY="0.5" CenterX="0.5"/>
<SkewTransform CenterY="0.5" CenterX="0.5"/>
<RotateTransform Angle="90" CenterY="0.5" CenterX="0.5"/>
<TranslateTransform/>
</TransformGroup>
</LinearGradientBrush.RelativeTransform>
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Gold" Offset="0.2"/>
<GradientStop Color="Gold" Offset="0.8"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Ellipse.Stroke>
</Ellipse>
<Ellipse x:Name="ellipseVeryHigh" HorizontalAlignment="Left" Height="200" Margin="-120,0,0,0" StrokeThickness="5" VerticalAlignment="Center" Width="400">
<Ellipse.Stroke>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<LinearGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform CenterY="0.5" CenterX="0.5"/>
<SkewTransform CenterY="0.5" CenterX="0.5"/>
<RotateTransform Angle="90" CenterY="0.5" CenterX="0.5"/>
<TranslateTransform/>
</TransformGroup>
</LinearGradientBrush.RelativeTransform>
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Gold" Offset="0.2"/>
<GradientStop Color="Gold" Offset="0.8"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Ellipse.Stroke>
</Ellipse>
</Grid>
</Window>
I am not sure whether it will have impact on performance but for readability for sure. One style for all eclipse elements, one resource for stroke etc.
<Window.Resources>
<Storyboard x:Key="Storyboard1" RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetProperty="(Shape.Stroke).(Brush.RelativeTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="ellipseLow"
Timeline.DesiredFrameRate="12" From="0" To="359" Duration="0:00:3.0" />
<DoubleAnimation Storyboard.TargetProperty="(Shape.Stroke).(Brush.RelativeTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="ellipseMedium"
Timeline.DesiredFrameRate="12" From="0" To="359" Duration="0:00:3.0" />
<DoubleAnimation Storyboard.TargetProperty="(Shape.Stroke).(Brush.RelativeTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="ellipseHigh"
Timeline.DesiredFrameRate="12" From="0" To="359" Duration="0:00:3.0" />
<DoubleAnimation Storyboard.TargetProperty="(Shape.Stroke).(Brush.RelativeTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="ellipseVeryHigh"
Timeline.DesiredFrameRate="12" From="0" To="359" Duration="0:00:3.0" />
</Storyboard>
<LinearGradientBrush x:Key="LinearBrush1" EndPoint="0.5,1" StartPoint="0.5,0">
<LinearGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform CenterY="0.5" CenterX="0.5"/>
<SkewTransform CenterY="0.5" CenterX="0.5"/>
<RotateTransform Angle="90" CenterY="0.5" CenterX="0.5"/>
<TranslateTransform/>
</TransformGroup>
</LinearGradientBrush.RelativeTransform>
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Gold" Offset="0.2"/>
<GradientStop Color="Gold" Offset="0.8"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
<Style TargetType="Ellipse">
<Setter Property="Stroke" Value="{StaticResource LinearBrush1}"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="StrokeThickness" Value="5"/>
</Style>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
</Window.Triggers>
<Grid x:Name="BackgroundGrid" Background="Black">
<Ellipse x:Name="ellipseLow" Height="800" Margin="-720,0,0,0" Width="1600"/>
<Ellipse x:Name="ellipseMedium" Height="600" Margin="-520,0,0,0" Width="1200"/>
<Ellipse x:Name="ellipseHigh" Height="400" Width="800" Margin="-320,0,0,0"/>
<Ellipse x:Name="ellipseVeryHigh" Height="200" Margin="-120,0,0,0" Width="400"/>
</Grid>

WPF border animation not working

I am trying to put an animation on a border as follows
<LinearGradientBrush x:Key="RedButtonBrushUp" StartPoint=".5,0" EndPoint=".5,1">
<GradientStop Color="#ffaaaa" Offset="0"/>
<GradientStop Color="#cc6666" Offset="0.6"/>
<GradientStop Color="#bb2222" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ButtonBrushUp" StartPoint=".5,0" EndPoint=".5,1">
<GradientStop Color="#aaccff" Offset="0"/>
<GradientStop Color="#7799ff" Offset="0.6"/>
<GradientStop Color="#555599" Offset="1"/>
</LinearGradientBrush>
<Border x:Name="BorderUp" BorderThickness="2,2,2,2" CornerRadius="4,4,4,4" Background="{StaticResource RedButtonBrushUp}">
<Border.Triggers>
<EventTrigger RoutedEvent="Border.Loaded">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Storyboard.TargetName="BorderUp"
Storyboard.TargetProperty="Background"
RepeatBehavior="Forever"
AutoReverse="True"
To="{StaticResource ButtonBrushUp}"
Duration="0:0:0.5" ></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
</Border>
But it says {StaticResource ButtonBrushUp} is an invalid type for this. What am I doing wrong?
The To can't accept such a change needed for the gradient brush stops.
Here is a working example of what you are trying to do
<Window.Resources>
<Storyboard x:Key="OnLoaded1">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="myBorder">
<EasingColorKeyFrame KeyTime="0:0:1" Value="#FFC53838"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded" SourceName="myBorder">
<BeginStoryboard Storyboard="{StaticResource OnLoaded1}"/>
</EventTrigger>
</Window.Triggers>
<Grid>
<StackPanel x:Name="stackPanel" Orientation="Vertical" HorizontalAlignment="Center">
<Border x:Name="myBorder" Background="#99FFFFFF" BorderThickness="3"
Margin="0,60,0,20" Padding="20" >
<Border.BorderBrush>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Border.BorderBrush>
<TextBlock>
This example shows how to have a border change color after an initial load.
</TextBlock>
</Border>
</StackPanel>

How to animate the StartPoint of LinearGradient

I have a LinearGradientBrush used as an OpacityMask and I want my animation to rotate the gradient, so I'm trying to animate the position of the StartPoint and EndPoint but I can't make it work for hours :(
<Style x:Key="NewContentStyle" TargetType="ContentPresenter">
<Setter Property="OpacityMask">
<Setter.Value>
<LinearGradientBrush x:Name="FillGradient" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0.5"/>
<GradientStop Color="Transparent" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
<Storyboard x:Key="NewContentStoryboard">
<PointAnimation Storyboard.TargetProperty="StartPoint" Storyboard.TargetName="FillGradient" From="0.5 0" To="0 0.5" Duration="00:00:1" />
<PointAnimation Storyboard.TargetProperty="EndPoint" Storyboard.TargetName="FillGradient" From="1 0.5" To="0 0.5" Duration="00:00:1"/>
</Storyboard>
I get an error "'FillGradient' name cannot be found in the name scope of 'System.Windows.Controls.ContentPresenter'."
Please try this:
<Storyboard x:Key="NewContentStoryboard">
<PointAnimation Storyboard.TargetProperty="OpacityMask.(LinearGradientBrush.StartPoint)" From="0.5 0" To="0 0.5" Duration="00:00:1" />
<PointAnimation Storyboard.TargetProperty="OpacityMask.(LinearGradientBrush.EndPoint)" From="1 0.5" To="0 0.5" Duration="00:00:1"/>
</Storyboard>

ColorAnimation Gradient On WPF

<LinearGradientBrush x:Key="BrushPrincipalBorderBlue" EndPoint="1.3,1" StartPoint="-0.2,0">
<GradientStop Color="#FF030637" Offset="1"/>
<GradientStop Color="#FF0E0F31" Offset="0.166"/>
<GradientStop Color="#FF2E2F70" Offset="0.629"/>
<GradientStop Color="#FF030637" Offset="0.63"/>
</LinearGradientBrush>
<Storyboard x:Key="GoToBlue">
<ColorAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="Background.GradientStops[3].Color" Duration="0:0:0.5"
To="{DynamicResource BrushPrincipalBorderBlue.GradientStops[3].Color}" />
</Storyboard>
How i can Set in the 'To' property to an GradientStop Color of my brush? because calling the way im calling it doesnt work.
The BrushPrincipalBorderBlue name is just a key it is not an actual LinearGradientBrush therefore it does not have any Propertys. I was able to get the error to go away by adding a name to the Brush. See if that works for you.
<Window.Resources>
<LinearGradientBrush x:Name="myBrush" x:Key="BrushPrincipalBorderBlue" EndPoint="1.3,1" StartPoint="-0.2,0">
<GradientStop Color="#FF030637" Offset="1"/>
<GradientStop Color="#FF0E0F31" Offset="0.166"/>
<GradientStop Color="#FF2E2F70" Offset="0.629"/>
<GradientStop Color="#FF030637" Offset="0.63"/>
</LinearGradientBrush>
<Storyboard x:Key="GoToBlue">
<ColorAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="Background.GradientStops[3].Color" Duration="0:0:0.5" To="{DynamicResource myBrush.GradientStops[3].Color}" />
</Storyboard>
The only way I was able to access the colors was to define them seperatly i.e.
<Window.Resources>
<Color x:Key="BrushPrincipalBorderBlue.Color1">
<Color.A>#FF</Color.A>
<Color.B>#03</Color.B>
<Color.R>#06</Color.R>
<Color.G>#37</Color.G>
</Color>
<Color x:Key="BrushPrincipalBorderBlue.Color2">
<Color.A>#FF</Color.A>
<Color.B>#0E</Color.B>
<Color.R>#0F</Color.R>
<Color.G>#31</Color.G>
</Color>
<Color x:Key="BrushPrincipalBorderBlue.Color3">
<Color.A>#FF</Color.A>
<Color.B>#2E</Color.B>
<Color.R>#2F</Color.R>
<Color.G>#70</Color.G>
</Color>
<Color x:Key="BrushPrincipalBorderBlue.Color4">
<Color.A>#FF</Color.A>
<Color.B>#03</Color.B>
<Color.R>#06</Color.R>
<Color.G>#37</Color.G>
</Color>
<LinearGradientBrush x:Key="BrushPrincipalBorderBlue" EndPoint="1.3,1" StartPoint="-0.2,0">
<GradientStop Color="{DynamicResource BrushPrincipalBorderBlue.Color1}" Offset="1"/>
<GradientStop Color="{DynamicResource BrushPrincipalBorderBlue.Color2}" Offset="0.166"/>
<GradientStop Color="{DynamicResource BrushPrincipalBorderBlue.Color3}" Offset="0.629"/>
<GradientStop Color="{DynamicResource BrushPrincipalBorderBlue.Color4}" Offset="0.63"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="BrushPrincipalBorderOriginal" EndPoint="1.3,1" StartPoint="-0.2,0">
<GradientStop Color="#FFFFFFFF" Offset="1"/>
<GradientStop Color="#FFFFFFFF" Offset="0.166"/>
<GradientStop Color="#FFFFFFFF" Offset="0.629"/>
<GradientStop Color="#FFFFFFFF" Offset="0.63"/>
</LinearGradientBrush>
</Window.Resources>
<Grid Name="myGrid" Background="{DynamicResource BrushPrincipalBorderOriginal}" >
<Grid.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="myGrid" Storyboard.TargetProperty="Background.GradientStops[3].Color" Duration="0:0:2" To="{DynamicResource BrushPrincipalBorderBlue.Color3}" AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
</Grid>
Not sure what you want to do but Offset is a double number, hence you need to use DoubleAnimation like this one:
<Canvas.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="BlackCanvasGradient"
Storyboard.TargetProperty="Offset"
From="0" To="0.8" Duration="0:0:2" >
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>

Resources