Iris Classon
Iris Classon - In Love with Code

Access storyboard from VisualStateManager/ access VisualState in code (programmatically)

As you might have found out (or not) you can’t access VisualStates by their name in code/programmatically. Setting a VisualState in code is also a bit of a hassle compared to declaring it in XAML, and then of course you can’t use Blend. If you try to access a named storyboard that is wrapped in a VisualState, then you will get a Null Reference Exception. Since I had a hard time finding a decent solution I would like to share with you two ways of solving this issue, and if you have any other solutions/can improve this code, please email or twitter me! I love feedback on my code, I have only been doing this for less than a year so my coding skills are not the best (yet) but it would be a shame not to share my solutions just because of of that :) So here you go, two ways:
The quick and dirty not so readable, my first solution to this issue
[sourcecode language=“csharp”]

//What I don’t like here is the use of ‘magic numbers’

var storyboard = VisualStateManager.GetVisualStateGroups(this.LayoutRoot)[1].States[2].Storyboard;

//
[/sourcecode]

How I do it (at the moment)
[sourcecode language=“csharp”]

//What I do like here is the readability, and since I will be using this a lot extensions seem like the best way to go about it

public sealed partial class GroupedItemsPage : Trainer.Common.LayoutAwarePage
{
void SomeMethod()
{
var storyboard = VisualStateManager.GetVisualStateGroups(this.LayoutRoot).Get(“TapStates”).States.Get(“PointerDown”).Storyboard;
}
}

public static class StateExtensions
{
public static VisualStateGroup Get(this IList stateGroups, string name)
{
return stateGroups.Single(x => x.Name == name);
}

    public static VisualState Get(this IList<VisualState> stateGroups, string name)  
    {  
        return stateGroups.Single(x => x.Name == name);  
    }  

}

[/sourcecode]

The VisualStates, wrapped in a Grid named “LayoutRoot”

[sourcecode language=“XML”]
<VisualStateManager.VisualStateGroups>







                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridView" Storyboard.TargetProperty="Padding">  
                        <DiscreteObjectKeyFrame KeyTime="0" Value="96,0,10,56"/>  
                    </ObjectAnimationUsingKeyFrames>  
                </Storyboard>  
            </VisualState>  

            <VisualState x:Name="Snapped">  
                <Storyboard>  
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">  
                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedBackButtonStyle}"/>  
                    </ObjectAnimationUsingKeyFrames>  
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="pageTitle" Storyboard.TargetProperty="Style">  
                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedPageHeaderTextStyle}"/>  
                    </ObjectAnimationUsingKeyFrames>  

                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemListView" Storyboard.TargetProperty="Visibility">  
                        <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>  
                    </ObjectAnimationUsingKeyFrames>  
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridView" Storyboard.TargetProperty="Visibility">  
                        <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>  
                    </ObjectAnimationUsingKeyFrames>  
                </Storyboard>  
            </VisualState>  
        </VisualStateGroup>  
        <VisualStateGroup x:Name="TapStates">  
            <VisualState x:Name="Normal" />  
            <VisualState x:Name="PointerDown">  
                <Storyboard x:Name="PressedAnimation">  
                    <PointerDownThemeAnimation TargetName="LogEntry" />  
                </Storyboard>  
            </VisualState>  
            <VisualState x:Name="PointerUp">  
                <Storyboard x:Name="ReleasedAnimation">  
                    <PointerUpThemeAnimation TargetName="LogEntry" />  
                </Storyboard>  
            </VisualState>  
        </VisualStateGroup>  
    </VisualStateManager.VisualStateGroups>  

[/sourcecode]

Comments

Leave a comment below, or by email.


Last modified on 2012-06-28

comments powered by Disqus