Here's what I'm trying to do:
Make control1 Visible, make control2 Collapsed, animate opacity from 1 to 0 on control 1 over .8 seconds.
immediately after that is done, do this:
Make control1 Collapsed, make control2 Visible, animate opacity from 0 to 1 on control2 over .8 seconds.
I just can't get it to be fluid and I'm out ideas. here's what I have:
<Storyboard x:Key="sb">
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.8000000" Storyboard.TargetName="MainTabControl" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Visible}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:00.8000000" Value="{x:Static Visibility.Collapsed}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.8000000" Storyboard.TargetName="MainTabControl" Storyboard.TargetProperty="(UIElement.Opacity)">
<LinearDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
<LinearDoubleKeyFrame KeyTime="00:00:00.8000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00.8000000" Duration="00:00:00.8000000" Storyboard.TargetName="SearchProjectsView" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Collapsed}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:00.8000000" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.8000000" Duration="00:00:00.8000000" Storyboard.TargetName="SearchProjectsView" Storyboard.TargetProperty="(UIElement.Opacity)">
<LinearDoubleKeyFrame KeyTime="00:00:00.0000000" Value="0"/>
<LinearDoubleKeyFrame KeyTime="00:00:00.8000000" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
It isn't clear from your question why you would animate the Opacity and Visbility at the same time, but your problem is that the animation of the Visibility of the second control should start immediately, not after 0.8 seconds.
This should work:
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="MainTabControl" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
<DiscreteObjectKeyFrame KeyTime="0:0:0.8" Value="{x:Static Visibility.Collapsed}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="SearchProjectsView" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Collapsed}"/>
<DiscreteObjectKeyFrame KeyTime="0:0:0.8" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation
Storyboard.TargetName="MainTabControl" Storyboard.TargetProperty="Opacity"
From="1" To="0" Duration="0:0:0.8"/>
<DoubleAnimation
Storyboard.TargetName="SearchProjectsView" Storyboard.TargetProperty="Opacity"
From="0" To="1" BeginTime="0:0:0.8" Duration="0:0:0.8"/>
</Storyboard>
Related
I have a trigger that fires off an OptionsShow storyboard animation when a button is clicked. This works with no problem. When I click an options button that I created, I made a grid fade in over it, similar to a custom tooltip. When the user leaves that grid, I make it fade out with the OptionsHide storyboard animation. If I leave the grid and quickly hover over the grid before it completely goes away, the grid constantly flashes.
It seems that the constant flashing occurs because the initial hide animation cannot complete, but I can't seem to figure out how to debug this. I don't have an "OnEnter" grid trigger to reshow the grid, so I'm not really sure when it shows the grid with opacity 100%, begins to fade and the constantly repeats this process.
If anyone has any experience with this, any help or info would be great.
<Window.Resources>
<Storyboard x:Key="OptionsShow">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Border">
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Border">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OptionsHide">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Border">
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
<DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="{x:Static Visibility.Collapsed}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Border">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<!--This is my button in my menu bar. On click I show my tooltip grid.-->
<EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button">
<BeginStoryboard Storyboard="{StaticResource OptionsShow}"/>
</EventTrigger>
<!--When I leave the tooltip grid, make the tooltip grid fade out.-->
<EventTrigger RoutedEvent="UIElement.MouseLeave" SourceName="Border">
<BeginStoryboard x:Name="OptionsHide_BeginStoryboard" Storyboard="{StaticResource OptionsHide}"/>
</EventTrigger>
</Window.Triggers>
I'm working on transitioning some code from silverlight to WPF, and my VisualStates are not working correctly.
I am using visualstatemanager to control the visibility of some text fields. I am not using any transitions to animate the change, I just want the fields to be collapsed in one state, then visible in another.
Xaml from silverlight:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="LostPasswordStates">
<VisualState x:Name="LostPassword_Start">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="lbl_UserName" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Visible" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="txt_UserName" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Visible" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="txt_UserName" Storyboard.TargetProperty="(TextBox.IsReadOnly)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="False" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="LostPassword_Success">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="lbl_UserName" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Collapsed" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="txt_UserName" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Collapsed" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="btn_Reset" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Collapsed" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
I get the following exception :
An unhandled exception of type 'System.Windows.Media.Animation.AnimationException' occurred in PresentationCore.dll
Additional information: Cannot animate the 'Visibility' property on a 'System.Windows.Controls.TextBox' using a 'System.Windows.Media.Animation.ObjectAnimationUsingKeyFrames'. For details see the inner exception.
So my question to you is:
If I can't use a System.Windows.Media.Animation.ObjectAnimationUsingKeyFrames for this, what should I be using?
This works for me, using .NET 4.5:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="LostPasswordStates">
<VisualState x:Name="LostPassword_Start">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="lbl_UserName" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="txt_UserName" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="txt_UserName" Storyboard.TargetProperty="(TextBox.IsReadOnly)">
<DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="LostPassword_Success">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="lbl_UserName" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="txt_UserName" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="btn_Reset" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
There are two changes to your current code:
Instead of "Collapsed" and "Visible", the Value is set to "{x:Static Visibility.Collapsed}" and "{x:Static Visibility.Visible}";
The IsReadOnly property uses a BooleanAnimationUsingKeyFrames instead of an ObjectAnimationUsingKeyFrames;
You can only animate properties of numeric types (double). Visibility can not be animated because it is enum an there is no way to animate this meaningfull.
If you want to fadeout something you can use the opacity property.
I have the following code:
<Storyboard x:Key="CounterStoryboard" >
<!-- Panel appear -->
<ObjectAnimationUsingKeyFrames Duration="0:0:0" Storyboard.TargetName="CounterPanel" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
<!-- 3-->
<DoubleAnimation
Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="CounterLabel3" From="1" To="0" Duration="0:0:1" BeginTime="0:0:0">
</DoubleAnimation>
<!-- 2 -->
<DoubleAnimation
Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="CounterLabel2" From="0" To="1" Duration="0:0:0" BeginTime="0:0:1">
</DoubleAnimation>
<DoubleAnimation
Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="CounterLabel2" From="1" To="0" Duration="0:0:1" BeginTime="0:0:1">
</DoubleAnimation>
<!-- 1 -->
<DoubleAnimation
Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="CounterLabel1" From="0" To="1" Duration="0:0:0" BeginTime="0:0:2">
</DoubleAnimation>
<DoubleAnimation
Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="CounterLabel1" From="1" To="0" Duration="0:0:1" BeginTime="0:0:2">
</DoubleAnimation>
<!-- Panel disappear -->
<ObjectAnimationUsingKeyFrames Duration="0:0:0" Storyboard.TargetName="CounterPanel" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0:0:3" Value="{x:Static Visibility.Collapsed}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
This acts like a counter, from 3 to 1. Everything works fine, except from the last part. The Panel disappear is not working. It should make the panel invisible, but it's still there...
What I'm doing wrong?
NOTE: I call the storyboard like this:
sb = (Storyboard)FindResource("CounterStoryboard");
sb = sb.Clone();
sb.Completed += sb_Completed;
sb.Begin(this);
Your last animation has a Duration of 0:0:0 yet you set KeyTime to 0:0:3 which is beyond duration time. You can change KeyTime to 0:0:0 and set BeginTime to 0:0:3
<ObjectAnimationUsingKeyFrames Duration="0:0:0" BeginTime="0:0:3" Storyboard.TargetName="CounterPanel" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Collapsed}"/>
</ObjectAnimationUsingKeyFrames>
I've created a button which changes its appearance when in different states, the way I do this (as a single example) when the button is being clicked down on:
<vsm:VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.Background).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="Green"/>
</ColorAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.RenderTransform). (TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.94"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.RenderTransform). (TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.94"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
Is there a way I could accomplish this using less code? I Just want the scale and colour to both instantly change to green when pressed, is there a way to do it without using keyframes?
Thanks for any help!
This can be written so:
<ColorAnimation Duration="0" To="Green" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.Background).(SolidColorBrush.Color)" />
<DoubleAnimation Duration="0" To="0.94" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" />
<DoubleAnimation Duration="0" To="0.94" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" />
General animations are easier to understand and to use, and there is very few cases when frame animations can be used isnted of general animations.
I want to change the source of an image using storyboard in silverlight blend on mouse over:
<VisualState x:Name="MouseOver">
<Storyboard>
---code here--
</Storyboard>
</VisualState>
Ok finally solved it :
On mouse hover i just turn out the visbility of an image to colapsed and made the visibility of other image to visible. That's it :)
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="fillColor">
<SplineDoubleKeyFrame KeyTime="0" Value=".35"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="image">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="hoverimage">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>