Jun 282012
 
 June 28, 2012  Posted by at 6:09 am WinRT Tagged with: , , , , ,  Add comments

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<VisualStateGroup> 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>
<VisualStateGroup x:Name="ApplicationViewStates">
<VisualState x:Name="FullScreenLandscape"/>
<VisualState x:Name="Filled"/>
<VisualState x:Name="FullScreenPortrait">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PortraitBackButtonStyle}"/>
</ObjectAnimationUsingKeyFrames>

<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>
<!–These are the states we are accessing–>
<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]

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

What is 6 + 5 ?
Please leave these two fields as-is:
IMPORTANT! To be able to proceed, you need to solve the following simple math (so we know that you are a human) :-)