Using Visual State Manager from a UserControl

To aid in an answer on StackOverflow that I had recently answered, I’m providing part of the response here.

The question was essentially, “what’s a way to use DataTriggers in Silverlight, without DataTriggers?”

I had suggested one idea would just to use VisualStates and a code behind file.

That’s what I’ve done here. I created an enum of type AnimateState, which has three possible values, Top, Left, and Right. By clicking on one of three buttons on the simple UI, it changes the value of the property, which in turn calls one of the VisualStates defined in the XAML.

In the example, it animates the position of the orange ellipse to various positions on the canvas.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace DemoShowVisualStateManager
{    
    public partial class MainPage : UserControl
    {
        private AnimateState _animateState;

        public MainPage()
        {
            InitializeComponent();
        }

        public AnimateState State
        {
            get { return _animateState; }

            set
            {
                if (_animateState != value && Enum.IsDefined(typeof(AnimateState), value))
                {
                    _animateState = value;

                    VisualStateManager.GoToState(this, value.ToString(), true);
                }
            }

        }

        private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            AnimateState state;
            if (AnimateState.TryParse((sender as Button).Content.ToString(), out state)) 
            {
                State = state;
            }
            
        }
    }

    public enum AnimateState
    {
        Top,
        Left,
        Right
    }
}

 

<UserControl x:Class="DemoShowVisualStateManager.MainPage"
    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"
    mc:Ignorable="d"
    Width="500" Height="500">

    <UserControl.Resources>
    </UserControl.Resources>
    <Canvas x:Name="LayoutRoot" Background="White">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="Positions">
                <VisualStateGroup.Transitions>
                    <VisualTransition GeneratedDuration="0:0:3"/>
                </VisualStateGroup.Transitions>
                <VisualState x:Name="Right">
                    <Storyboard>
                        <DoubleAnimation Duration="0" To="389" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="ball" d:IsOptimized="True"/>
                        <DoubleAnimation Duration="0" To="198" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="ball" d:IsOptimized="True"/>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Left">
                    <Storyboard>
                        <DoubleAnimation Duration="0" To="-199" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="ball" d:IsOptimized="True"/>
                        <DoubleAnimation Duration="0" To="390" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="ball" d:IsOptimized="True"/>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Top"/>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

        <Ellipse x:Name="ball" Stroke="#FFFFD9B8" RenderTransformOrigin="0.5,0.5" Height="100" VerticalAlignment="Top" Canvas.Top="10" Width="100" Canvas.Left="200">
            <Ellipse.RenderTransform>
                <CompositeTransform/>
            </Ellipse.RenderTransform>
            <Ellipse.Fill>
                <RadialGradientBrush Center="0.388,0.328" GradientOrigin="0.388,0.328" RadiusX="0.63">
                    <GradientStop Color="#FFF97200" Offset="1"/>
                    <GradientStop Color="#FFFFD9B8"/>
                </RadialGradientBrush>
            </Ellipse.Fill>
        </Ellipse>
        <Button Content="Left" Height="33" Canvas.Left="200" Canvas.Top="229" Width="100" Click="Button_Click"/>
        <Button Content="Top" Height="33" Canvas.Left="200" Canvas.Top="266" Width="100" Click="Button_Click"/>
        <Button Content="Right" Height="33" Canvas.Left="200" Canvas.Top="303" Width="100" Click="Button_Click"/>

    </Canvas>
</UserControl>

image