[WinRT] Interact with VisualState and Storyboard with MVVM – Part I

At this time, Behavior and DataTrigger doesn’t exist in WinRT and that’s too bad because it was very easy to interact with Storyboard or VisualState. So, how to do that with WinRT component ? The answer is DependencyObject !

public class InteractionGrid: DependencyObject
{

    #region VisualState

    public static string GetVisualState(DependencyObject obj)
    {
        return (string)obj.GetValue(VisualStateProperty);
    }

    public static void SetVisualState(DependencyObject obj, string value)
    {
        obj.SetValue(VisualStateProperty, value);
    }

    public static readonly DependencyProperty VisualStateProperty = 
DependencyProperty.RegisterAttached("VisualState", typeof(string), typeof(InteractionGrid), new PropertyMetadata(null, (s, e) =>
    {
        var propertyName = (string)e.NewValue;
        var ctrl = s as Control;
        if (ctrl == null)
            throw new InvalidOperationException("This attached property only supports types derived from Control.");
        VisualStateManager.GoToState(ctrl, propertyName, true);
    }));

    #endregion

    #region Storyboard

    public static string GetStoryboard(DependencyObject obj)
    {
        return (string)obj.GetValue(StoryboardProperty);
    }

    public static void SetStoryboard(DependencyObject obj, string value)
    {
        obj.SetValue(StoryboardProperty, value);
    }

    public static readonly DependencyProperty StoryboardProperty =
DependencyProperty.RegisterAttached("Storyboard", typeof(string), typeof(InteractionGrid), new PropertyMetadata(null, (s, e) =>
    {
        var storyboardName = (string)e.NewValue;
        var ctrl = s as FrameworkElement;
        if (ctrl == null)
            throw new InvalidOperationException("This attached property only supports types derived from Control.");

        object sb;
        if (!ctrl.Resources.TryGetValue(storyboardName, out sb) || !(sb is Storyboard))
            return;

        var storyboard = sb as Storyboard;

        var action = (string)s.GetValue(StoryboardActionProperty);
        switch (action)
        {
            case "Begin":
                storyboard.Begin();
                break;
            case "Pause":
                storyboard.Pause();
                break;
            case "Stop":
                storyboard.Stop();
                break;
        }
    }));

    public static string GetStoryboardAction(DependencyObject obj)
    {
        return (string)obj.GetValue(StoryboardActionProperty);
    }

    public static void SetStoryboardAction(DependencyObject obj, string value)
    {
        obj.SetValue(StoryboardActionProperty, value);
    }

    public static readonly DependencyProperty StoryboardActionProperty =
DependencyProperty.RegisterAttached("StoryboardAction", typeof(string), typeof(InteractionGrid), new PropertyMetadata("Begin"));

    #endregion
}

And how to use it :

<Grid UI:InteractionGrid.Storyboard="{Binding StoryboardName}" UI:InteractionGrid.StoryboardAction="{Binding StoryboardAction}" />

In the next episode, I will go deeper with storyboard and work with the Completed event to have more complex scenarios.

Have fun !

One Comment

Leave a Reply