WPF simple brush animation causes a performance issue - wpf
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>
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.
Set Fill to LinearGradientBrush on Button Click
For reference, I am using this MSDN tutorial: https://msdn.microsoft.com/en-us/library/bb613545(v=vs.100).aspx I have finished the tutorial, and I simply wanted to change the Click EventTrigger animation from the 360 spin to a simple change of the LinearGradientBrush. My GradientStopCollections as per the tutorial. One is an altered one that I want to use in the animation when I click the button <GradientStopCollection x:Key="MyGlassGradientStopsResource"> <GradientStop Offset="0.2" Color="WhiteSmoke" /> <GradientStop Offset="0.4" Color="Transparent" /> <GradientStop Offset="0.5" Color="WhiteSmoke" /> <GradientStop Offset="0.75" Color="Transparent" /> <GradientStop Offset="0.9" Color="WhiteSmoke" /> <GradientStop Offset="1" Color="Transparent" /> </GradientStopCollection> <GradientStopCollection x:Key="MyRedGlassGradientStopsResource"> <GradientStop Offset="0.2" Color="IndianRed" /> <GradientStop Offset="0.4" Color="Transparent" /> <GradientStop Offset="0.5" Color="IndianRed" /> <GradientStop Offset="0.75" Color="Transparent" /> <GradientStop Offset="0.9" Color="IndianRed" /> <GradientStop Offset="1" Color="Transparent" /> </GradientStopCollection> <LinearGradientBrush x:Key="MyGlassBrushResource" GradientStops="{StaticResource MyGlassGradientStopsResource}" Opacity="0.75" StartPoint="0,0" EndPoint="1,1" /> <LinearGradientBrush x:Key="MyRedGlassBrushResource" GradientStops="{StaticResource MyRedGlassGradientStopsResource}" Opacity="0.75" StartPoint="0,0" EndPoint="1,1" /> The button itself. The rectangle being affected is the glassCube rectangle. <Style TargetType="{x:Type Button}"> <Setter Property="Background" Value="{StaticResource GrayBlueGradientBrush}" /> <Setter Property="Width" Value="90" /> <Setter Property="Margin" Value="10" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" ClipToBounds="True"> <!-- Outer rectangle with rounded corners --> <Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="Transparent" RadiusX="20" RadiusY="20" Stroke="{TemplateBinding Background}" StrokeThickness="5" /> <!-- Inner rectangle with rouded corners --> <Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="{TemplateBinding Background}" RadiusX="20" RadiusY="20" Stroke="Transparent" StrokeThickness="20" /> <!-- Glass Rectangle --> <Rectangle x:Name="glassCube" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="{StaticResource MyGlassBrushResource}" Opacity="0" RadiusX="10" RadiusY="10" RenderTransformOrigin="0.5,0.5" StrokeThickness="2"> <Rectangle.Stroke> <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> <LinearGradientBrush.GradientStops> <GradientStop Offset="0.0" Color="LightBlue" /> <GradientStop Offset="1.0" Color="Gray" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Rectangle.Stroke> <!-- These tranforms have no effect as they are declared here. The reason the transforms are included is to be targets for animation (See later) --> <Rectangle.RenderTransform> <TransformGroup> <ScaleTransform /> <RotateTransform /> </TransformGroup> </Rectangle.RenderTransform> <!-- A BevelBitmapEffect if applied to give the button a "Bevelled" look --> <Rectangle.BitmapEffect> <BevelBitmapEffect /> </Rectangle.BitmapEffect> </Rectangle> <!-- Present content (text) of the button --> <DockPanel Name="myContentPresenterDockPanel"> <ContentPresenter x:Name="myContentPresenter" Margin="20" Content="{TemplateBinding Content}" TextBlock.Foreground="Black" /> </DockPanel> </Grid> </ControlTemplate> <!---Snipped the triggers--> </Setter.Value> And this is the trigger I am trying to use to change the Fill of the glassCube rectangle from the MyGlassGradientStopsResource brush to the MyGlassGradientStopsResource brush. <EventTrigger RoutedEvent="Button.Click"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <ColorAnimation Duration="0:0:0.5" Storyboard.TargetName="glassCube" Storyboard.TargetProperty="Rectangle.Fill" To="{StaticResource MyRedGlassBrushResource}"/> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> However, trying to do this gives me an XAMLParseException. The error in the error list shows as An object of the type "System.Windows.Media.LinearGradientBrush" cannot be applied to a property that expects the type "System.Nullable`1[[System.Windows.Media.Color, PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]". Any idea what I might be doing wrong? I've tried finding out how to change a Fill to a different LinearGradientBrush in an EventTrigger, but to no avail. I may just suck at wording my searches, or at searching in general. Any help is greatly appreciated
I did some modification of your style. Also, i fixed your Storyboard. It should now work properly. <Style TargetType="{x:Type Button}"> <Setter Property="Background" Value="{StaticResource GrayBlueGradientBrush}" /> <Setter Property="Width" Value="90" /> <Setter Property="Margin" Value="10" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" ClipToBounds="True"> <Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="Transparent" RadiusX="20" RadiusY="20" Stroke="{TemplateBinding Background}" StrokeThickness="5" /> <Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="{TemplateBinding Background}" RadiusX="20" RadiusY="20" Stroke="Transparent" StrokeThickness="20" /> <Rectangle x:Name="glassCube" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Opacity="1" RadiusX="10" RadiusY="10" RenderTransformOrigin="0.5,0.5" StrokeThickness="2"> <Rectangle.Style> <Style TargetType="Rectangle"> <Setter Property="Fill" Value="{StaticResource MyGlassBrushResource}"></Setter> </Style> </Rectangle.Style> <Rectangle.Stroke> <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> <LinearGradientBrush.GradientStops> <GradientStop Offset="0.0" Color="LightBlue" /> <GradientStop Offset="1.0" Color="Gray" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Rectangle.Stroke> <Rectangle.RenderTransform> <TransformGroup> <ScaleTransform /> <RotateTransform /> </TransformGroup> </Rectangle.RenderTransform> <!-- A BevelBitmapEffect if applied to give the button a "Bevelled" look --> <Rectangle.BitmapEffect> <BevelBitmapEffect /> </Rectangle.BitmapEffect> </Rectangle> <!-- Present content (text) of the button --> <DockPanel Name="myContentPresenterDockPanel" HorizontalAlignment="Center"> <ContentPresenter x:Name="myContentPresenter" Content="{TemplateBinding Content}" TextBlock.Foreground="Black" /> </DockPanel> </Grid> <ControlTemplate.Triggers> <EventTrigger RoutedEvent="Button.Click"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="glassCube" Storyboard.TargetProperty="Fill" Duration="0:0:0.5" BeginTime="0"> <ObjectAnimationUsingKeyFrames.KeyFrames> <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource MyRedGlassBrushResource}" /> </ObjectAnimationUsingKeyFrames.KeyFrames> </ObjectAnimationUsingKeyFrames> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> Note You cannot set a Brush as ColorAnimation. Use a ObjectAnimationUsingKeyFrames instead. If you still need a BrushAnimation, have a look here
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>
EventTrigger RoutedEvent amimation in wpf xaml
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
How to add XAML storyboard animation to a full blown WPF Custom Control in an XBAP?
We are creating custom WPF controls (not user controls) for an XBAP application and we would like to add a storyboard animation to scale the control to be 110% of its original size when the mouse hovers over it. We've used Blend to create the storyboard and it compiles just fine...however, when we run, it does not animate up to 110%. I've read bits and pieces here and there that you can't do storyboard animations in XAML for custom controls. Does anyone know how to do this for custom controls fully in XAML? Here is the XAML for our custom control: <Style TargetType="{x:Type controls:ExitButton}"> <Style.Resources> <Storyboard x:Key="OnMouseEnter"> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="{x:Null}" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/> <SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="1.1"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="{x:Null}" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/> <SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="1.1"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </Style.Resources> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Trigger.EnterActions> <BeginStoryboard Storyboard="{StaticResource OnMouseEnter}" x:Name="OnMouseEnter_BeginStoryboard"/> </Trigger.EnterActions> <Setter Property="BitmapEffect"> <Setter.Value> <OuterGlowBitmapEffect GlowColor="Blue" GlowSize="4"/> </Setter.Value> </Setter> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="BitmapEffect"> <Setter.Value> <OuterGlowBitmapEffect GlowColor="Blue" GlowSize="8"/> </Setter.Value> </Setter> </Trigger> </Style.Triggers> <Setter Property="ToolTip" Value="Exit this Application" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type controls:ExitButton}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <Viewbox x:Name="ControlViewBox"> <Grid x:Name="ExitApplication" Width="35" Height="50"> <Grid.RowDefinitions> <RowDefinition Height="5" /> <RowDefinition Height="25" /> <RowDefinition Height="15" /> </Grid.RowDefinitions> <Viewbox Grid.Row="1" Width="25" x:Name="ImageViewBox"> <Canvas Width="23" Height="23" HorizontalAlignment="Center"> <Path Width="22.9708" Height="22.9703" Canvas.Left="4.06802e-005" Canvas.Top="0" Stretch="Fill" Data="F1 M 16.1087,1.25732C 16.1087,1.25732 12.4594,4.90935 11.4834,5.88135L 11.4834,5.88135C 10.5141,4.91203 6.86068,1.25871 6.86068,1.25871L 6.86068,1.25871C 5.18604,-0.416016 2.93538,-0.42131 1.25407,1.26131L 1.25407,1.26131C -0.417969,2.93335 -0.417969,5.18799 1.25407,6.86272L 1.25407,6.86272C 1.25407,6.86272 4.90739,10.5146 5.87939,11.4866L 5.87939,11.4866C 4.91138,12.4561 1.25806,16.1067 1.25806,16.1067L 1.25806,16.1067C -0.415283,17.7827 -0.415283,20.0374 1.26204,21.7134L 1.26204,21.7134C 2.9327,23.388 5.18604,23.3853 6.86068,21.7107L 6.86068,21.7107C 6.86068,21.7107 10.5114,18.0614 11.4834,17.0894L 11.4834,17.0894C 12.4527,18.0614 16.1087,21.7174 16.1087,21.7174L 16.1087,21.7174C 17.7861,23.3893 20.0367,23.388 21.7113,21.7134L 21.7113,21.7134C 23.3901,20.0347 23.3887,17.7853 21.7167,16.112L 21.7167,16.112C 21.7167,16.112 18.0607,12.4561 17.0887,11.4841L 17.0887,11.4841C 18.0607,10.5107 21.714,6.86003 21.714,6.86003L 21.714,6.86003C 23.3887,5.18269 23.3901,2.93335 21.7167,1.25732L 21.7167,1.25732C 20.878,0.418701 19.8953,0 18.9141,0L 18.9141,0C 17.9314,0 16.9487,0.418701 16.1087,1.25732 Z "> <Path.Fill> <LinearGradientBrush StartPoint="0.945183,0.945154" EndPoint="0.0547729,0.0547262"> <LinearGradientBrush.GradientStops> <GradientStop Color="#FFB12702" Offset="0"/> <GradientStop Color="#FFD02F00" Offset="0.093399"/> <GradientStop Color="#FFE87A5F" Offset="1"/> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Path.Fill> </Path> <Path Width="9.9987" Height="6.8707" Canvas.Left="11.246" Canvas.Top="0.665356" Stretch="Fill" Data="F1 M 18.9114,0.665359C 18.0847,0.663986 17.2727,1.03606 16.5807,1.72803L 11.9567,6.35466L 11.246,7.06404L 11.7194,7.53606L 12.4287,6.82666L 17.0567,2.20134C 18.262,1.03606 19.5647,1.03467 20.7727,2.20271L 21.2447,1.72932C 20.5553,1.03865 19.7434,0.665359 18.9194,0.665359L 18.9114,0.665359 Z "> <Path.Fill> <LinearGradientBrush StartPoint="0.616568,0.713077" EndPoint="1.02849,0.713077"> <LinearGradientBrush.RelativeTransform> <TransformGroup> <SkewTransform CenterX="0.616568" CenterY="0.713077" AngleX="21.0093" AngleY="0"/> <RotateTransform CenterX="0.616568" CenterY="0.713077" Angle="235.505"/> </TransformGroup> </LinearGradientBrush.RelativeTransform> <LinearGradientBrush.GradientStops> <GradientStop Color="#FFC12900" Offset="0"/> <GradientStop Color="#FFFFE4DE" Offset="1"/> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Path.Fill> </Path> <Path Width="5.72795" Height="5.72534" Canvas.Left="0.660726" Canvas.Top="0.665359" Stretch="Fill" Data="F1 M 1.72607,1.73332C 1.03402,2.42268 0.662028,3.23601 0.660726,4.05998L 0.660726,4.05998C 0.662028,4.88802 1.0367,5.69865 1.73136,6.3907L 2.20207,5.91731C 1.0367,4.7093 1.0367,3.40935 2.19938,2.20671L 2.19938,2.20671C 3.40739,1.03735 4.70874,1.03606 5.91675,2.20532L 6.38867,1.73071C 5.69401,1.03735 4.88338,0.665359 4.05672,0.665359L 4.05672,0.665359C 3.22868,0.665359 2.41805,1.03735 1.72607,1.73332 Z "> <Path.Fill> <LinearGradientBrush StartPoint="0.593564,0.59328" EndPoint="1.16939,0.59328"> <LinearGradientBrush.RelativeTransform> <TransformGroup> <SkewTransform CenterX="0.593564" CenterY="0.59328" AngleX="0.0259795" AngleY="0"/> <RotateTransform CenterX="0.593564" CenterY="0.59328" Angle="225.013"/> </TransformGroup> </LinearGradientBrush.RelativeTransform> <LinearGradientBrush.GradientStops> <GradientStop Color="#FFC12900" Offset="0"/> <GradientStop Color="#FFFFE4DE" Offset="1"/> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Path.Fill> </Path> <Path Width="6.86931" Height="9.99202" Canvas.Left="0.66471" Canvas.Top="11.2507" Stretch="Fill" Data="F1 M 6.3527,11.9561L 1.73136,16.5827C 1.0367,17.2734 0.663411,18.0867 0.664714,18.9106L 0.664714,18.9106C 0.663411,19.7374 1.03939,20.5507 1.73275,21.2427L 2.20605,20.7707L 2.20467,20.7707C 1.0367,19.5614 1.0367,18.2613 2.20207,17.0547L 6.82739,12.4321L 7.53402,11.7227L 7.06201,11.2507L 6.3527,11.9561 Z "> <Path.Fill> <LinearGradientBrush StartPoint="0.713103,0.616728" EndPoint="1.12533,0.616728"> <LinearGradientBrush.RelativeTransform> <TransformGroup> <SkewTransform CenterX="0.713103" CenterY="0.616728" AngleX="-20.9846" AngleY="0"/> <RotateTransform CenterX="0.713103" CenterY="0.616728" Angle="214.508"/> </TransformGroup> </LinearGradientBrush.RelativeTransform> <LinearGradientBrush.GradientStops> <GradientStop Color="#FFC12900" Offset="0"/> <GradientStop Color="#FFFFE4DE" Offset="1"/> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Path.Fill> </Path> </Canvas> </Viewbox> <TextBlock Grid.Row="2" Text="exit" HorizontalAlignment="Center" FontFamily="Calibri" Foreground="#FFFFFFFF" RenderTransformOrigin="0.5,0.5" VerticalAlignment="Center" FontSize="18"> <TextBlock.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1"/> <SkewTransform AngleX="0" AngleY="0"/> <RotateTransform Angle="0"/> <TranslateTransform X="0" Y="0"/> </TransformGroup> </TextBlock.RenderTransform></TextBlock> </Grid> </Viewbox> </Border> </ControlTemplate> </Setter.Value> </Setter> <Setter Property="RenderTransformOrigin" Value="0.5,0.5"/> <Setter Property="RenderTransform"> <Setter.Value> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1"/> <SkewTransform AngleX="0" AngleY="0"/> <RotateTransform Angle="0"/> <TranslateTransform X="0" Y="0"/> </TransformGroup> </Setter.Value> </Setter> </Style>
It is possible ... I just think you need to move some stuff around. In particular, you need to move your Storyboard into the ControlTemplate.Resources section ... and your triggers into the ControlTemplate.Triggers section. I actually built a quick sample to try this out ... and it works. Here it is: <Style TargetType="{x:Type controls:ExitButton}"> <Setter Property="RenderTransformOrigin" Value="0.5,0.5"/> <Setter Property="RenderTransform"> <Setter.Value> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1"/> <SkewTransform AngleX="0" AngleY="0"/> <RotateTransform Angle="0"/> <TranslateTransform X="0" Y="0"/> </TransformGroup> </Setter.Value> </Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type controls:ExitButton}"> <ControlTemplate.Resources> <Storyboard x:Key="OnMouseEnter"> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="{x:Null}" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/> <SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="1.1"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="{x:Null}" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/> <SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="1.1"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </ControlTemplate.Resources> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <Viewbox x:Name="ControlViewBox"> <Grid x:Name="ExitApplication" Width="35" Height="50"> <Grid.RowDefinitions> <RowDefinition Height="5" /> <RowDefinition Height="25" /> <RowDefinition Height="15" /> </Grid.RowDefinitions> <Viewbox Grid.Row="1" Width="25" x:Name="ImageViewBox"> <Canvas Width="23" Height="23" HorizontalAlignment="Center"> <Path Width="22.9708" Height="22.9703" Canvas.Left="4.06802e-005" Canvas.Top="0" Stretch="Fill" Data="F1 M 16.1087,1.25732C 16.1087,1.25732 12.4594,4.90935 11.4834,5.88135L 11.4834,5.88135C 10.5141,4.91203 6.86068,1.25871 6.86068,1.25871L 6.86068,1.25871C 5.18604,-0.416016 2.93538,-0.42131 1.25407,1.26131L 1.25407,1.26131C -0.417969,2.93335 -0.417969,5.18799 1.25407,6.86272L 1.25407,6.86272C 1.25407,6.86272 4.90739,10.5146 5.87939,11.4866L 5.87939,11.4866C 4.91138,12.4561 1.25806,16.1067 1.25806,16.1067L 1.25806,16.1067C -0.415283,17.7827 -0.415283,20.0374 1.26204,21.7134L 1.26204,21.7134C 2.9327,23.388 5.18604,23.3853 6.86068,21.7107L 6.86068,21.7107C 6.86068,21.7107 10.5114,18.0614 11.4834,17.0894L 11.4834,17.0894C 12.4527,18.0614 16.1087,21.7174 16.1087,21.7174L 16.1087,21.7174C 17.7861,23.3893 20.0367,23.388 21.7113,21.7134L 21.7113,21.7134C 23.3901,20.0347 23.3887,17.7853 21.7167,16.112L 21.7167,16.112C 21.7167,16.112 18.0607,12.4561 17.0887,11.4841L 17.0887,11.4841C 18.0607,10.5107 21.714,6.86003 21.714,6.86003L 21.714,6.86003C 23.3887,5.18269 23.3901,2.93335 21.7167,1.25732L 21.7167,1.25732C 20.878,0.418701 19.8953,0 18.9141,0L 18.9141,0C 17.9314,0 16.9487,0.418701 16.1087,1.25732 Z "> <Path.Fill> <LinearGradientBrush StartPoint="0.945183,0.945154" EndPoint="0.0547729,0.0547262"> <LinearGradientBrush.GradientStops> <GradientStop Color="#FFB12702" Offset="0"/> <GradientStop Color="#FFD02F00" Offset="0.093399"/> <GradientStop Color="#FFE87A5F" Offset="1"/> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Path.Fill> </Path> <Path Width="9.9987" Height="6.8707" Canvas.Left="11.246" Canvas.Top="0.665356" Stretch="Fill" Data="F1 M 18.9114,0.665359C 18.0847,0.663986 17.2727,1.03606 16.5807,1.72803L 11.9567,6.35466L 11.246,7.06404L 11.7194,7.53606L 12.4287,6.82666L 17.0567,2.20134C 18.262,1.03606 19.5647,1.03467 20.7727,2.20271L 21.2447,1.72932C 20.5553,1.03865 19.7434,0.665359 18.9194,0.665359L 18.9114,0.665359 Z "> <Path.Fill> <LinearGradientBrush StartPoint="0.616568,0.713077" EndPoint="1.02849,0.713077"> <LinearGradientBrush.RelativeTransform> <TransformGroup> <SkewTransform CenterX="0.616568" CenterY="0.713077" AngleX="21.0093" AngleY="0"/> <RotateTransform CenterX="0.616568" CenterY="0.713077" Angle="235.505"/> </TransformGroup> </LinearGradientBrush.RelativeTransform> <LinearGradientBrush.GradientStops> <GradientStop Color="#FFC12900" Offset="0"/> <GradientStop Color="#FFFFE4DE" Offset="1"/> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Path.Fill> </Path> <Path Width="5.72795" Height="5.72534" Canvas.Left="0.660726" Canvas.Top="0.665359" Stretch="Fill" Data="F1 M 1.72607,1.73332C 1.03402,2.42268 0.662028,3.23601 0.660726,4.05998L 0.660726,4.05998C 0.662028,4.88802 1.0367,5.69865 1.73136,6.3907L 2.20207,5.91731C 1.0367,4.7093 1.0367,3.40935 2.19938,2.20671L 2.19938,2.20671C 3.40739,1.03735 4.70874,1.03606 5.91675,2.20532L 6.38867,1.73071C 5.69401,1.03735 4.88338,0.665359 4.05672,0.665359L 4.05672,0.665359C 3.22868,0.665359 2.41805,1.03735 1.72607,1.73332 Z "> <Path.Fill> <LinearGradientBrush StartPoint="0.593564,0.59328" EndPoint="1.16939,0.59328"> <LinearGradientBrush.RelativeTransform> <TransformGroup> <SkewTransform CenterX="0.593564" CenterY="0.59328" AngleX="0.0259795" AngleY="0"/> <RotateTransform CenterX="0.593564" CenterY="0.59328" Angle="225.013"/> </TransformGroup> </LinearGradientBrush.RelativeTransform> <LinearGradientBrush.GradientStops> <GradientStop Color="#FFC12900" Offset="0"/> <GradientStop Color="#FFFFE4DE" Offset="1"/> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Path.Fill> </Path> <Path Width="6.86931" Height="9.99202" Canvas.Left="0.66471" Canvas.Top="11.2507" Stretch="Fill" Data="F1 M 6.3527,11.9561L 1.73136,16.5827C 1.0367,17.2734 0.663411,18.0867 0.664714,18.9106L 0.664714,18.9106C 0.663411,19.7374 1.03939,20.5507 1.73275,21.2427L 2.20605,20.7707L 2.20467,20.7707C 1.0367,19.5614 1.0367,18.2613 2.20207,17.0547L 6.82739,12.4321L 7.53402,11.7227L 7.06201,11.2507L 6.3527,11.9561 Z "> <Path.Fill> <LinearGradientBrush StartPoint="0.713103,0.616728" EndPoint="1.12533,0.616728"> <LinearGradientBrush.RelativeTransform> <TransformGroup> <SkewTransform CenterX="0.713103" CenterY="0.616728" AngleX="-20.9846" AngleY="0"/> <RotateTransform CenterX="0.713103" CenterY="0.616728" Angle="214.508"/> </TransformGroup> </LinearGradientBrush.RelativeTransform> <LinearGradientBrush.GradientStops> <GradientStop Color="#FFC12900" Offset="0"/> <GradientStop Color="#FFFFE4DE" Offset="1"/> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Path.Fill> </Path> </Canvas> </Viewbox> <TextBlock Grid.Row="2" Text="exit" HorizontalAlignment="Center" FontFamily="Calibri" Foreground="#FFFFFFFF" RenderTransformOrigin="0.5,0.5" VerticalAlignment="Center" FontSize="18"> <TextBlock.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1"/> <SkewTransform AngleX="0" AngleY="0"/> <RotateTransform Angle="0"/> <TranslateTransform X="0" Y="0"/> </TransformGroup> </TextBlock.RenderTransform></TextBlock> </Grid> </Viewbox> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Trigger.EnterActions> <BeginStoryboard Storyboard="{StaticResource OnMouseEnter}" x:Name="OnMouseEnter_BeginStoryboard"/> </Trigger.EnterActions> <Setter Property="BitmapEffect"> <Setter.Value> <OuterGlowBitmapEffect GlowColor="Blue" GlowSize="4"/> </Setter.Value> </Setter> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="BitmapEffect"> <Setter.Value> <OuterGlowBitmapEffect GlowColor="Blue" GlowSize="8"/> </Setter.Value> </Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>