I Have Animation In My ResourceDictionary But I Want Call Animation In My C# Code.
This ResourceDictionary Add To My Resources App
Example:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<BeginStoryboard x:Key="PuzzleFall">
<Storyboard Storyboard.TargetName="RenderT" Storyboard.TargetProperty="X">
<DoubleAnimationUsingKeyFrames Duration="0:0:3" BeginTime="0:0:0">
<SplineDoubleKeyFrame Value="0" KeySpline="1 0,0.95 0" KeyTime="0:0:3"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="0:0:3.06" Duration="0:0:1.5">
<SplineDoubleKeyFrame Value="50" KeySpline="0 1,0 1" KeyTime="0:0:1.5"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="0:0:3.08" Duration="0:0:1">
<SplineDoubleKeyFrame Value="0" KeySpline="1 0,1 0" KeyTime="0:0:1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="0:0:4.1" Duration="0:0:1">
<SplineDoubleKeyFrame Value="15" KeySpline="0 1,0 1" KeyTime="0:0:1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="0:0:4.15" Duration="0:0:0.5">
<SplineDoubleKeyFrame Value="0" KeySpline="1 0,1 0" KeyTime="0:0:0.5"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</ResourceDictionary>
Then I Want Run This Animation In C# Code.
Thanks.
You probably should not put the Storyboard which is the main component inside a BeginStoryboard especially if you use code. EIther way. you can get the Storyboard using FindResource.
In your current setup something like this:
var beginsb = (BeginStoryboard)FindResource("PuzzleFall");
var sb = beginsb.Storyboard;
sb.Begin();
Related
I've made an opacity animation using Blend on one my two UserControls, deleted <UserControl.Resources>, <UserControl.Triggers> and Storyboard.TargetName from that, placed it in App.xaml and it looks like:
<Storyboard x:Key="Loaded">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" >
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
when I call it in code like this before setting the Content of my ContentControl:
Storyboard sb = FindResource("Loaded") as Storyboard;
sb.begin(uc1);
content.Content = uc1;
//and
Storyboard sb = FindResource("Loaded") as Storyboard;
sb.begin(uc2);
content.Content = uc2;
it works as expected. For the transform animation, I've deleted the TransformGroup as well in addition to those above and now it looks like:
<Storyboard x:Key="Unloaded">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="-800"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
If I call it in the same way, I get this error:
System.InvalidOperationException: ''[Unknown]' property does not point to a DependencyObject in path '(0).(1)[3].(2)'.'
How to fix the problem?
You will need to add a RenderTransform to your UserControl which is similar to the Storyboard.TargetProperty which currently expects a TransformGroup with 4th child as TranslateTransform.
Add the below code to each of your two UserControls:
<UserControl x:Class="YourUserControl"
...>
<UserControl.RenderTransform>
<TransformGroup>
<RotateTransform/>
<ScaleTransform/>
<SkewTransform/>
<TranslateTransform/>
</TransformGroup>
</UserControl.RenderTransform>
I am trying to play a bit with the badged control from Mahapps. Is it possible to change the size of the badge (not just the color/value/etc..)
Finally I am trying to do some sort of bigger pulse effect when the badge value changed, I tried the following for the color but it didn't work:
<Controls:Badged.Triggers>
<EventTrigger RoutedEvent="Controls:Badged.BadgeChanged">
<EventTrigger.EnterActions>
<BeginStoryboard Name="AnimateVisibilityChanged">
<Storyboard>
<ColorAnimation Duration="0:0:0.5"
From="#FFEE4709"
To="Green"
BeginTime="0:0:0"
Storyboard.TargetProperty="(Controls:Badged.BadgeBackground).(SolidColorBrush.Color)">
</ColorAnimation>
<ColorAnimation Duration="0:0:0.5"
From="Green"
To="Transparent"
AutoReverse="True"
BeginTime="0:0:2"
RepeatBehavior="0:0:2.5"
Storyboard.TargetProperty="(Controls:Badged.BadgeBackground).(SolidColorBrush.Color)">
</ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.EnterActions>
<EventTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="AnimateVisibilityChanged" />
</EventTrigger.ExitActions>
</EventTrigger>
</Controls:Badged.Triggers>
The next step if this would work is to also increase the size more than it's already increasing
It looks like I will answer to my question:
the animation didn't work because I used EnterActions instead of simply Actions (EventTrigger.Actions)
To change the size of the badge when the value changes I had to use BadgeChangedStoryboard property and replace with my own:
<SineEase x:Key="BadgeEase"
EasingMode="EaseOut" />
<Storyboard x:Key="BadgeChangedStoryboard">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0"
Value="2.3" />
<EasingDoubleKeyFrame EasingFunction="{StaticResource BadgeEase}"
KeyTime="0:0:0.3"
Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0"
Value="2.3" />
<EasingDoubleKeyFrame EasingFunction="{StaticResource BadgeEase}"
KeyTime="0:0:0.3"
Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
To change the size change both the easing double key frame Value
I have a frame within my main page that I have set up to stretch/slide over on a button click. I do not want the frame to stretch/slide on the first button click but rather when the user clicks that same button a second time.
XAML:
<Storyboard x:Key="FrameSlide">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="currentPage">
<SplineDoubleKeyFrame KeyTime="0" Value="1"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.7" Value="1.217"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="currentPage">
<SplineDoubleKeyFrame KeyTime="0" Value="0"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.7" Value="-126"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="FrameSlideBack">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="currentPage">
<SplineDoubleKeyFrame KeyTime="0" Value="1.217"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.7" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="currentPage">
<SplineDoubleKeyFrame KeyTime="0" Value="-126"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.7" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="UIElement.MouseLeftButtonDown" SourceName="TransmitBTN">
<BeginStoryboard x:Name="FrameSlide" Storyboard="{StaticResource FrameSlide}"/>
</EventTrigger>
<EventTrigger RoutedEvent="UIElement.MouseLeftButtonDown" SourceName="PatientBTN">
<BeginStoryboard x:Name="FrameSlideBack" Storyboard="{StaticResource FrameSlideBack}"/>
</EventTrigger>
</Window.Triggers>
I've tried using the storyboard.stop() / storyboard.being() in my VB.net code for the button, but it seems like the xaml is over ridding the vb code. I've tired doing if statements where my frame is a certain width then do nothing else trigger the animation.
Not sure where to go from here.
Thanks
I am answering this in C# as i dont know VB but from what I am told you can change it easily?
The answer I can come with us is make an event on the button, button_click, within the class create a public property. In the event increment the property and when it reaches two, trigger your story board.
XAML for button event:
<Button x:Name="button" Content="Button" Click="Button_OnClick"
C# code:
public partial class StackOverFlowExample
{
public StackOverFlowExample()
{
InitializaComponent();
buttonClickCounter = 0;
}
public int buttonClickCounter {get; set;}
private void Button_Click(object sender, RoutedEventArgs e)
{
buttonClickCounter++;
if (buttonClickCounter == 2)
{
buttonClickCounter = 0;
Storyboard sb = Application.Current.Resources["FrameSlide"] as
Storyboard;
if (sb.IsSealed)
sb = sb.Clone();
Storyboard.SetTarget(sb, this.NextButton);
sb.Completed += delegate { };
sb.Begin();
}
e.Handled = true;
}
}
I want to reuse a storyboad defined in a resourcedictionnary and referenced in App.xaml
<Storyboard x:Key="ShowWindowStoryboard">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"
>
<EasingDoubleKeyFrame KeyTime="0:0:0.3"
Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"
>
<EasingDoubleKeyFrame KeyTime="0:0:0.3"
Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)"
>
<EasingDoubleKeyFrame KeyTime="0:0:0.3"
Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
and here the code that gave an exception
Storyboard sb = (FindResource("ShowWindowStoryboard") as Storyboard).Clone();
DoubleAnimation da0 = sb.Children[0] as DoubleAnimation;
/* Exception here da0 is null*/
Storyboard.SetTarget(da0, uc);
DoubleAnimation da1 = sb.Children[1] as DoubleAnimation;
Storyboard.SetTarget(da1, uc);
DoubleAnimation da2 = sb.Children[2] as DoubleAnimation;
Storyboard.SetTarget(da2, uc);
sb.Begin();
i have also checked that sb.children.Count == 3 as expected.
You have to add a TransformGroup to the RenderTransform of your uc control. I will be adding a TransformGroup to an Image. The same will work for your control uc.
XAML
<Image Source="untitled.bmp" Name="ImgDemo">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform/>
</TransformGroup>
</Image.RenderTransform>
</Image>
If you have to add TransformGroup in code behind, you can use following before calling Story.Begin:
TransformGroup transformGroup = new TransformGroup();
transformGroup.Children.Add(new ScaleTransform(1,1));
uc.RenderTransform = transformGroup;
Your Storyboard.TargetProperty should reflect the signature of the object that you want the storyboard to be applied to. This is why you were facing the exception. Also, you might want to change your Storyboard a little to actually see the changes on the object. Like,
<Storyboard x:Key="ShowWindowStoryboard">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"
>
<EasingDoubleKeyFrame KeyTime="0:0:0.3"
Value="0.5" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"
>
<EasingDoubleKeyFrame KeyTime="0:0:0.3"
Value="0.5" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)"
>
<EasingDoubleKeyFrame KeyTime="0:0:0.3"
Value="0.5" />
</DoubleAnimationUsingKeyFrames>
Note that the values are changed so that the animations will be noticeable. Finally, I do see that your code behind on calling the storyboard does not use proper casting. So you might wanna consider using the following,
Storyboard sb = (FindResource("ShowWindowStoryboard") as Storyboard).Clone();
DoubleAnimationUsingKeyFrames da0 = sb.Children[0] as DoubleAnimationUsingKeyFrames;
Storyboard.SetTarget(da0, ImgDemo);
DoubleAnimationUsingKeyFrames da1 = sb.Children[1] as DoubleAnimationUsingKeyFrames;
Storyboard.SetTarget(da1, ImgDemo);
DoubleAnimationUsingKeyFrames da2 = sb.Children[2] as DoubleAnimationUsingKeyFrames;
Storyboard.SetTarget(da2, ImgDemo);
sb.Begin();
Good luck!
The storyBoard_Completed event is invoked in a delay of about half a second after the visual animation had finished.
Would be glad for some more eyes to check out my Storyboard XAML:
<Storyboard x:Key="blaAnimation" Completed="storyBoard_Completed">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="bla1" Storyboard.TargetProperty="Offset" Completed="bla_Completed">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" x:Name="bla1StartKeyFrame"/>
<EasingDoubleKeyFrame Value="-10.2" KeyTime="0:0:1">
<EasingDoubleKeyFrame.EasingFunction>
<PowerEase EasingMode="EaseIn"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="-20" x:Name="bla1Animation">
<EasingDoubleKeyFrame.EasingFunction>
<ElasticEase EasingMode="EaseOut" Oscillations="5" Springiness="20"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="bla2" Storyboard.TargetProperty="Offset" BeginTime="0:0:0.1" Completed="bla2_Completed">
<DiscreteDoubleKeyFrame Value="0" KeyTime="0:0:0.1" x:Name="bla2StartKeyFrame"/>
<EasingDoubleKeyFrame Value="-10.2" KeyTime="0:0:1.1">
<EasingDoubleKeyFrame.EasingFunction>
<PowerEase EasingMode="EaseIn"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:2.1" Value="-20" x:Name="bla2Animation">
<EasingDoubleKeyFrame.EasingFunction>
<ElasticEase EasingMode="EaseOut" Oscillations="5" Springiness="20"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="bla3" Storyboard.TargetProperty="Offset" BeginTime="0:0:0.18" Completed="bla3_Completed">
<DiscreteDoubleKeyFrame Value="0" KeyTime="0:0:0.2" x:Name="bla3StartKeyFrame"/>
<EasingDoubleKeyFrame Value="-10.2" KeyTime="0:0:1.2">
<EasingDoubleKeyFrame.EasingFunction>
<PowerEase EasingMode="EaseIn"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:2.2" Value="-20" x:Name="bla3Animation">
<EasingDoubleKeyFrame.EasingFunction>
<ElasticEase EasingMode="EaseOut" Oscillations="5" Springiness="20"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
Thanks in advance,
--Ran.
When in doubt - Blend it
Following on from comment trail (above), the end result is "If you have access to it (or can afford it), always use Expression Blend for creating animation storyboards".
Blend is the best way to learn animation which can get very complex quite easily. Blend also optimises certainly animations automatically for you.
As you know there is no support at all in VS 2010 for authoring animation, except with XAML, and that is error prone. It is also very hard to visualise multiple animations in your head with only text to go by :)