locked
Very Simple Show / Hide State RRS feed

  • Question

  • I find animations a bit confusing and would like to know some best practices.  I'm a little embarrassed by my inability to perform this simple action:

    Use case:  I want to click a button to toggle the visibility of a note.

     

    Should I use states?

    Should I just toggle the visibility in code?

    Should I bind the visibility to a datastore property?

    Should I create a Storyboard?

     

    I was able to create two simple states, but after it finishes the transition of showing the note, it immediately disappears.  Help?

     

    Are there better tutorials or links for learning Animations than what is provided with Blend help?  I find that external docs for Blend 4 is still kind of lacking...

     

    Wednesday, December 1, 2010 1:28 AM

All replies

  • The best documentation for things like this are generally the WPF or SL docs, because most of the details are determined by the platform.

     

    As you have discovered, there are often multiple ways of doing things, and the best way depends on your needs.

     

    If this is a prototype, states are probably the easiest way to go, I'm not sure about the issue about it disappearing, can you post the xaml so I can take a look?

     

    If this is production work, you will need to think about what else you need to do. If this is WPF you could use triggers and a storyboard. If it is SL you could use states, or you could databind to a property on a viewmodel.

    Sorry for the "it depends" answer, but it really does :)

    Wednesday, December 1, 2010 2:30 PM
    Moderator
  • For your decision, which technique you are going to use to achieve what you want, you should also take into account the performance. Using a transition or a storyboard is less performant than simply switching the visibility on and off from visible to hidden (and vice versa). This in fact depends especially on how complex you built your visual object(s) (did you use one or more effect like for example a DropShadowEffect) and / or how complex your storyboard is.
    Thursday, December 2, 2010 7:55 AM
  • Am just getting back to this... was working on actual wireframes, now have a little time to do the small 'fancy' items.

     

    I have a box of content, let's say 20 words.  I want to click a button to show more, and have the box grow to show 50 words.  This is representing a simple DIV display within HTML.

     

    Base

    [ here are some words.  click below to see more...]

    {button}

     

    Open State

    [ here are some words.  click below to see more.

    hey, look at me, i can show more words.

    if you click the button again this will shrink back

    ]

    {clicked button}

     

    Back to Base

    [ here are some words.  click below to see more...]

    {button}

     

    So it is likely best to do this by creating a simple state.  Key then is capturing the current state and being able to click the button a second time to have it go back to the base.  With this 'double action' for a button I can't just drag on an 'ActivateStateAction' behavior.

    I imagine this is a relatively common use case - have an example? 

    UPDATE:  Below is what I tried and it isn't working proper - I click once, I see a transition and then it goes back to original immediately.  Am I just not creating the state properly?

     

    <UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:pc="http://schemas.microsoft.com/prototyping/2010/controls" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:pi="http://schemas.microsoft.com/prototyping/2010/interactivity"
    	x:Class="TesterScreens.Screen_1"
    	Width="1024" Height="768" mc:Ignorable="d">
    
    	<Grid x:Name="LayoutRoot" Background="White">
    		<VisualStateManager.VisualStateGroups>
    			<VisualStateGroup x:Name="VisualStateGroup">
    				<VisualStateGroup.Transitions>
    					<VisualTransition GeneratedDuration="0" To="VisualState">
    						<Storyboard>
    							<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="sketchRectangleSL">
    								<EasingDoubleKeyFrame KeyTime="0" Value="1.077"/>
    								<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1.462"/>
    							</DoubleAnimationUsingKeyFrames>
    							<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="sketchRectangleSL">
    								<EasingDoubleKeyFrame KeyTime="0" Value="4"/>
    								<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="24"/>
    							</DoubleAnimationUsingKeyFrames>
    							<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="myButton">
    								<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
    								<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="40"/>
    							</DoubleAnimationUsingKeyFrames>
    						</Storyboard>
    					</VisualTransition>
    					<VisualTransition From="VisualState" GeneratedDuration="0">
    						<Storyboard>
    							<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="myButton">
    								<EasingDoubleKeyFrame KeyTime="0" Value="40"/>
    								<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
    							</DoubleAnimationUsingKeyFrames>
    							<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="sketchRectangleSL">
    								<EasingDoubleKeyFrame KeyTime="0" Value="1.462"/>
    								<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1.077"/>
    							</DoubleAnimationUsingKeyFrames>
    							<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="sketchRectangleSL">
    								<EasingDoubleKeyFrame KeyTime="0" Value="24"/>
    								<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="4"/>
    							</DoubleAnimationUsingKeyFrames>
    						</Storyboard>
    					</VisualTransition>
    				</VisualStateGroup.Transitions>
    				<VisualState x:Name="VisualState">
    					<Storyboard>
    						<DoubleAnimation Duration="0" To="1.077" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="sketchRectangleSL" d:IsOptimized="True"/>
    						<DoubleAnimation Duration="0" To="4" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="sketchRectangleSL" d:IsOptimized="True"/>
    					</Storyboard>
    				</VisualState>
    			</VisualStateGroup>
    		</VisualStateManager.VisualStateGroups>
    		<pc:SketchRectangleSL x:Name="sketchRectangleSL" Height="104" Margin="400,80,384,0" Style="{StaticResource Rectangle-Sketch}" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5">
    			<pc:SketchRectangleSL.RenderTransform>
    				<CompositeTransform/>
    			</pc:SketchRectangleSL.RenderTransform>
    		</pc:SketchRectangleSL>
    		<Button x:Name="myButton" Content="Button" HorizontalAlignment="Right" Height="32" Margin="0,200,384,0" Style="{StaticResource Button-Sketch}" VerticalAlignment="Top" Width="96" RenderTransformOrigin="0.5,0.5">
    			<Button.RenderTransform>
    				<CompositeTransform/>
    			</Button.RenderTransform>
    
    		</Button>
    	</Grid>
    </UserControl>

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    namespace TesterScreens
    {
    	public partial class Screen_1 : UserControl
    	{
    		public Screen_1()
    		{
    			// Required to initialize variables
    			InitializeComponent();
    			myButton.Click +=new System.Windows.RoutedEventHandler(myButton_Click);
    		}
    
    		public void Button_Click()
    		{
    
    		}
    
    		private void myButton_Click(object sender, System.Windows.RoutedEventArgs e)
    		{
    			if(btnState.Equals("closed"))
    			{
    				this.btnState = "open";
    				VisualStateManager.GoToState(this, "VisualState", true);
    			} else {
    				this.btnState = "closed";
    				VisualStateManager.GoToState(this, "*", true);
    			}
    		}
    
    		private string btnState = "closed";
    		
    	}
    }

    Tuesday, December 21, 2010 3:52 AM