Powered by MSDN

US - English
NEW! Silverlight 5 is available Learn More

Programmatically setting Animation attributes inside Vi... RSS

5 replies

Last post Jan 03, 2009 11:36 PM by r2musings

(0)
  • r2musings

    r2musings

    Member

    48 Points

    20 Posts

    Programmatically setting Animation attributes inside VisualStateManager

    Dec 26, 2008 04:01 PM | LINK

    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); } } }
     

     

     

    Rik Robinson
    Senior Consultant - Wintellect
    MCPD-EAD, MCTS-WPF
    Blog: www.r2musings.com
    Web: www.wintellect.com
  • swildermuth

    swildermuth

    Star

    8438 Points

    1547 Posts

    Re: Programmatically setting Animation attributes inside VisualStateManager

    Dec 27, 2008 09:20 PM | LINK

    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.

    Shawn Wildermuth
    MVP, Speaker and Author

    Web Workshop (HTML5/CSS/MVC4)
    San Fran, CA - Mar 28-30, 2012
    Dallas, TX: Apr 29-May 1, 2012
    https://agilitrain.com/Workshop/Info/Web_Workshop
  • r2musings

    r2musings

    Member

    48 Points

    20 Posts

    Re: Programmatically setting Animation attributes inside VisualStateManager

    Dec 27, 2008 11:37 PM | LINK

    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?

     

     

    Rik Robinson
    Senior Consultant - Wintellect
    MCPD-EAD, MCTS-WPF
    Blog: www.r2musings.com
    Web: www.wintellect.com
  • swildermuth

    swildermuth

    Star

    8438 Points

    1547 Posts

    Re: Re: Programmatically setting Animation attributes inside VisualStateManager

    Dec 28, 2008 01:08 AM | LINK

    (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?
    Shawn Wildermuth
    MVP, Speaker and Author

    Web Workshop (HTML5/CSS/MVC4)
    San Fran, CA - Mar 28-30, 2012
    Dallas, TX: Apr 29-May 1, 2012
    https://agilitrain.com/Workshop/Info/Web_Workshop
  • r2musings

    r2musings

    Member

    48 Points

    20 Posts

    Re: Programmatically setting Animation attributes inside VisualStateManager

    Dec 28, 2008 10:35 PM | LINK

    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. 

     

    Rik Robinson
    Senior Consultant - Wintellect
    MCPD-EAD, MCTS-WPF
    Blog: www.r2musings.com
    Web: www.wintellect.com
  • r2musings

    r2musings

    Member

    48 Points

    20 Posts

    Re: Programmatically setting Animation attributes inside VisualStateManager

    Jan 03, 2009 11:36 PM | LINK

    I have blogged about how to initialize Silverlight Animations (including those in a VSM) here:

    http://www.r2musings.com/2009/01/04/InitializingTheFROMValueOfASilverlight2Animation.aspx

     

     

    Rik Robinson
    Senior Consultant - Wintellect
    MCPD-EAD, MCTS-WPF
    Blog: www.r2musings.com
    Web: www.wintellect.com