This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Start Storyboard When Text Changes
I've created a animation:
<phone:PhoneApplicationPage
...>
<phone:PhoneApplicationPage.Resources>
<Storyboard x:Name="MessageFadeInOut" Storyboard.TargetProperty="Opacity">
<DoubleAnimation From="0" To="1" Duration="0:0:1" BeginTime="0:0:0" />
<DoubleAnimation From="1" To="1" Duration="0:0:1" BeginTime="0:0:1" />
<DoubleAnimation From="1" To="0" Duration="0:0:1" BeginTime="0:0:2" />
</Storyboard>
</phone:PhoneApplicationPage.Resources>
What I'm trying to do where is have something fade in, stay for a bit then fade out.
I trigger it by:
private void Unit_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
Storyboard sb = this.Resources["MessageFadeInOut"] as Storyboard;
Storyboard.SetTarget(sb, this.Message);
sb.Begin();
}
But on the sb.Begin() I get "System.InvalidOperationException". How come? Message is a Image
I'm not sure what "Message" is in this context, and that might be the reason why you're seeing this exception. Or it might not be .
Either way, you shouldn't grab Storyboards and start those manually. You should use VisualStateManager to manage your visual states by encapsulating a storyboard in each state. You can read more about this # Start Storyboard When Text Changes
A good way to get started in VSM would be to watch these videos by Steve White in the Expression Blend 2 launch:
Adding Control States # http://msdn.microsoft.com/en-us/expression/ff898424
Create Custom Buttons # http://msdn.microsoft.com/en-us/expression/ff921363
Customize a Checkbox’s Checkmark # http://msdn.microsoft.com/en-us/expression/ff921365
Use an In-State Animation # http://msdn.microsoft.com/en-us/expression/ff921380
Each of these videos is part of a series, so consider watching the rest of the series. There are also articles you can read # http://www.interact-sw.co.uk/iangblog/2008/06/10/visual-state
Related
I am trying to animate a UserControl along a Cubic Bezier Curve.
This is the path I want the UserControl to be following:
<Path Stroke="Green" StrokeThickness="1" Data="M100,500 C275,200 825,200 1100,500" />
This is the code I have tried to use, but I have only found a way to animate along a straight line:
<Storyboard x:Name="MyAnimation">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ObjectTranslateTransform" Storyboard.TargetProperty="X" Duration="0:0:5">
<LinearDoubleKeyFrame Value="1100" KeyTime="0:0:5"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ObjectTranslateTransform" Storyboard.TargetProperty="Y" Duration="0:0:5">
<LinearDoubleKeyFrame Value="500" KeyTime="0:0:5"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
The only thing I have found that is talking about Bezier Curves is SplineDoubleKeyFrame. However, I can not get this to work even close to what I am looking for.
I have done this before in WPF by using MatrixAnimationUsingPath and DoubleAnimationUsingPath but these classes are not available in UWP. How do I animate a UserObject along a Path in UWP?
EDIT:
This is the code I have used for SplineDoubleKeyFrame:
<Storyboard x:Name="MyAnimation">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ObjectTranslateTransform" Storyboard.TargetProperty="X" Duration="0:0:5">
<SplineDoubleKeyFrame Value="1100" KeyTime="0:0:5" KeySpline="0.25,0.0 0.75,0.0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ObjectTranslateTransform" Storyboard.TargetProperty="Y" Duration="0:0:5">
<SplineDoubleKeyFrame Value="500" KeyTime="0:0:5" KeySpline="0.0,0.4 0.0,0.4"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
This is however only moving in a horizontal line at decreasing speed. I do not understand what the value for KeySpline should be.
You've mentioned in the question about it but the only way without creating the bezier reducing function yourself is via DoubleAnimationUsingKeyFrames using SplineDoubleKeyFrame.
In the MSDN docs there's a good example: https://learn.microsoft.com/en-us/windows/uwp/graphics/key-frame-and-easing-function-animations
You'll want an initial key frame - so a basic linear key frame at time = 0 and value = x to set the initial value.
Then a SplineDoubleKeyFrame with the bezier control points, value at your final value and time at your ending time
Can you post the code you've tried and what was wrong with the result?
I have a number of scenarios where I am doing simple WPF storyboard animations as such.
<Storyboard x:Key="MyTextBlockStoryBoard" RepeatBehavior="Forever">
<DoubleAnimation AutoReverse="True"
Duration="0:0:8"
From="0.0"
Storyboard.TargetName="MyTextBlock"
Storyboard.TargetProperty="(Canvas.Left)"
To="500.0" />
</Storyboard>
However I need to be able to set the To value in this animation to a dynamic value which is equivalent to UserControl.ActualWidth - MyTextBlock.ActualWidth. I understand that obviously I can easily create a Storyboard as above programmatically but I am hoping to stay inside Xaml world.
My inkling is that the only way I can achieve this is through implementing my own IValueConverter but I am hoping that there might be a easier way to achieve my desired output?
I need to do a simple game , which the player should tap the pictures in a time limit
and when the player taps the picture , i want to make animation of the picture fading out
I am using Visual Studio 2012 Express for Windows Phone
I think it's has something to do with OpacityProperty
Am not asking for the whole code to do it , i only want a helpful way to start
Just create a Storyboard animation changing the Opacity of the image, something like
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="ImageName"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:1"
/>
</Storyboard>
I have set up a textblock to set the string "ALARM" added to it when the alrm clock goes off. The code is working fine for this process. I am trying to make this string "ALARM" (or the textblock itself) flash when the alarm goes off.
I am able to work out the codes to make the string "ALARM" fade in fade out using mouse events but cant figure out how to make it happen w/o the need for mouse events. I tried textBlock_Loaded event and that doesn't work. I want the fade in fade out to be ongoing forever in a loop to create a flashing effect.
Please advice if there is an event that would fit my need. Been trying one by one down the list of available events with no success. My codes for the mouse events is below. Appreciate any advice. Thanks.
private void textBlock3_MouseLeave(object sender, MouseEventArgs e)
{
TextBlock textblk = (TextBlock)sender;
DoubleAnimation animation = new DoubleAnimation(0, TimeSpan.FromSeconds(2));
textblk.BeginAnimation(TextBlock.OpacityProperty, animation);
}
private void textBlock3_MouseEnter(object sender, MouseEventArgs e)
{
TextBlock textblk = (TextBlock)sender;
DoubleAnimation animation = new DoubleAnimation(1, TimeSpan.FromSeconds(2));
textblk.BeginAnimation(TextBlock.OpacityProperty, animation);
}
All you need is an EventTrigger with the "Loaded" event. Set the RepeatBehavior to "Forever" so that the Storyboard keeps repeating, and AutoReverse to "True":
<TextBlock x:Name="textBlock3" Text="hello world">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever" AutoReverse="True">
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Duration="0:0:1"
To="0"
/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
I have two overlapping (in same position, having the same size) MediaElements. They will contain images. The opacity of one element will be set to 1.0 and the opacity of the other set to 0.0. The idea here would be a simple transition for a slide-show type deal. When it's time to display the next slide, the background element loads a picture and the opacity of both elements switches gradually.
I tried (successfully) to implement this behavior using System.Timers, only to find that having more than some arbitrary number of timers in the same application would cause .NET to randomly spawn and cede control of timer_elapsed to several different threads. This caused unpredictable results and generally made me question my sanity.
So, I decided to do the same thing, but with System.Threads and their Sleep functions. For whatever reason, gradually cycling the opacity worked perfectly with the insane timers but fails utterly with threads. And it fails in a ridiculous way. The opacity of both elements does change, but there's no in between. The element is shown either with opacity at 1.0 or 0.0. Otherwise I would notice that roughly half the pictures weren't being cycled through.
After much googling, I thought perhaps the priority of the thread that the opacity changes were occurring on was somehow keeping the UI elements from being rendered immediately. But then I recalled that because I was using dispatcher invocations on the media elements, all of the action was taking place on the main thread anyway, so it wouldn't make a difference.
Contemplate the following code: https://gist.github.com/956093
As suggested you should use the native animations; i have come accross this thread issue before as well and in general i try to avoid using Dispatchers, i pretty much only use them to modify data if i must (e.g. ObservableCollection cannot be modified in a background thread, don't know any other examples actually).
You could still use normal threads, they work well if you use bindings to update the UIElements which nicely bypasses the dispatching issue.
Animation example:
<Grid Name="testGrid" Tag="2">
<Grid.Resources>
<Storyboard x:Key="FadeAnim2to1">
<DoubleAnimation Storyboard.Target="{x:Reference img1}"
Storyboard.TargetProperty="Opacity"
Duration="0:0:1" To="1"/>
<DoubleAnimation Storyboard.Target="{x:Reference img2}"
Storyboard.TargetProperty="Opacity"
Duration="0:0:1" To="0"/>
</Storyboard>
<Storyboard x:Key="FadeAnim1to2">
<DoubleAnimation Storyboard.Target="{x:Reference img1}"
Storyboard.TargetProperty="Opacity"
Duration="0:0:1" To="0"/>
<DoubleAnimation Storyboard.Target="{x:Reference img2}"
Storyboard.TargetProperty="Opacity"
Duration="0:0:1" To="1"/>
</Storyboard>
</Grid.Resources>
<Image x:Name="img1" Source="Images/Default.ico" Width="200" Height="200" Opacity="0"/>
<Image x:Name="img2" Source="Images/Error.ico" Width="200" Height="200"/>
</Grid>
<Button Content="Fade" Click="Button1_Click"/>
private void Button1_Click(object sender, RoutedEventArgs e)
{
Storyboard anim;
if ((string)testGrid.Tag == "1") //This is just for brevity, you should of course not use the Tag to store state information, let alone number strings
{
anim = testGrid.Resources["FadeAnim1to2"] as Storyboard;
testGrid.Tag = "2";
}
else
{
anim = testGrid.Resources["FadeAnim2to1"] as Storyboard;
testGrid.Tag = "1";
}
anim.Begin();
}