Skip to main content
Microsoft Silverlight
Home Forums General Silverlight Programming Programming with .NET - General Programmatically setting Animation attributes inside VisualStateManager
5 replies. Latest Post by r2musings on January 3, 2009.
(0)
r2musings
Member
48 points
20 Posts
12-26-2008 12:01 PM |
I am trying to programmatically set the "From" value of an Animation. I have done it many times in the past when working directly with my Storyboard, but I get an exception when I try to do this when the Storyboard (and Animation is part of a VisualStateManager. Probably easier to demo with code... a really simple example (including showing how it works when using a Storyboard directly) is below. I appreciate any insight into why this will not work.
Thanks in advance, Rik
XAML:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="PassingValuesToVsm.Page" Width="1000" Height="800" Background="#FF87B87B" xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <UserControl.Resources> <Storyboard x:Name="MoveRectangle"> <DoubleAnimation x:Name="notInVsmLeft" Storyboard.TargetName="theRectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" To="0" Duration="0:0:0.5" /> </Storyboard> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="#FF747768"> <vsm:VisualStateManager.VisualStateGroups> <vsm:VisualStateGroup x:Name="CircleStates"> <vsm:VisualState x:Name="Left"/> <vsm:VisualState x:Name="Right"> <Storyboard> <DoubleAnimation x:Name="inVsmLeft" Storyboard.TargetName="theCircle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" To="0" Duration="0:0:0.5" /> </Storyboard> </vsm:VisualState> </vsm:VisualStateGroup> </vsm:VisualStateManager.VisualStateGroups> <Rectangle Height="100" HorizontalAlignment="Left" VerticalAlignment="Top" Width="100" Stroke="#FF000000" x:Name="theRectangle" Opacity="1" Fill="#FFC80D0D" Margin="8,220,0,0"> <Rectangle.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform/> <TranslateTransform/> </TransformGroup> </Rectangle.RenderTransform> </Rectangle> <Button HorizontalAlignment="Left" Margin="8,340,0,0" VerticalAlignment="Top" Content="Move without Vsm" x:Name="MoveWithoutVsmButton" Click="MoveWithoutVsmButton_Click"/> <Button HorizontalAlignment="Left" Margin="8,0,0,268" Content="Move with Vsm" VerticalAlignment="Bottom" d:LayoutOverrides="Height" x:Name="MoveWithVsmButton" Click="MoveWithVsmButton_Click"/> <Ellipse Height="100" HorizontalAlignment="Left" Margin="8,0,0,300" x:Name="theCircle" VerticalAlignment="Bottom" Width="100" Fill="#FF005A20" Stroke="#FF000000" RenderTransformOrigin="0.5,0.5"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform/> <TranslateTransform/> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> </Grid> </UserControl>
Code:
namespace PassingValuesToVsm { public partial class Page : UserControl { public Page() { // Required to initialize variables InitializeComponent(); } private void MoveWithoutVsmButton_Click(object sender, RoutedEventArgs e) { // this works notInVsmLeft.From = 800; (MoveRectangle as Storyboard).Begin(); } private void MoveWithVsmButton_Click(object sender, RoutedEventArgs e) { // attempting to set the From value in the animation declared in the XAML for VisualStateManager // throws this exception: // // System.NullReferenceException was unhandled by user code // Message="Object reference not set to an instance of an object." //StackTrace: // at PassingValuesToVsm.Page.MoveWithVsmButton_Click(Object sender, RoutedEventArgs e) // at System.Windows.Controls.Primitives.ButtonBase.OnClick() // at System.Windows.Controls.Button.OnClick() // at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e) // at System.Windows.Controls.Control.OnMouseLeftButtonUp(Control ctrl, EventArgs e) // at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName) inVsmLeft.From = 800; VisualStateManager.GoToState(this, "Right", true); } } }
swilder...
Star
8436 points
1,546 Posts
12-27-2008 5:20 PM |
The problem here is that you are changing a Style and styles are applied once and only once so changing the underlying style (where the VSM is) won't propogate out to the controls. If this is what you want, you're likely going to have to do it in a non-VSM or a custom VSM scenario that doesn't involve a style.
12-27-2008 7:37 PM |
Thanks, Shawn.
I knew that Styles only get applied once, but I don't understand how using the VSM is equivalent to using a Style. Can you explain?
12-27-2008 9:08 PM |
(Sorry, I misread the entire question)... I think your problem is that you are trying to set a "from" which the VSM doesn't use believe it or not. The whole idea of the storyboards in a VSM are to move *TO* a state so the from isn't calculated. Sounds like you're trying to make something move with an inline VSM. Why not set the property on the item to 800 instead of setting the VSM then going to the state. that would yield the same results, no?
12-28-2008 6:35 PM |
OK, after a dive in Reflector I *think* that I see where the FROM value is all but ignored inside VSM and given that your solution sounded a like a perfect one.
So, now I set the Left Property of theCircle and it works ONCE. Strange....animation happens on first click and all subsequent clicks just place theCircle at the left position and leave it...no animation to TO value.
I thought maybe I should be interacting with a TranslateTranform instead of the width and that didn't work correctly either...worked once...just like the Width. I will try to see if there is another issue and report back.
I have gotten around my original problem by just skipping the VSM for the animation that I need to set a TO value and using VSM for those that I don't. The original requirement was that I had a custom dialog that I wanted an Open and Closed state for...however, the Open animation was to start from the mouse click position and so hence the need to initialize the starting position. Again, I got around it by just creating a Show and Hide storyboard outside of VSM.
01-03-2009 7:36 PM |
I have blogged about how to initialize Silverlight Animations (including those in a VSM) here: http://www.r2musings.com/2009/01/04/InitializingTheFROMValueOfASilverlight2Animation.aspx
I have blogged about how to initialize Silverlight Animations (including those in a VSM) here:
http://www.r2musings.com/2009/01/04/InitializingTheFROMValueOfASilverlight2Animation.aspx