Creating State Handling Markup with XAML
By Ken Getz | November 15, 2012
When you create an application, your goal (besides ensuring that the application does what it needs to do) is to make sure that it looks good, and works well across a variety of form factors, display sizes, and view states. Your app should look good and work well on an 11" tablet, a laptop screen, or a 30" desktop monitor. It should look good and work well whether the screen is in portrait or landscape mode, whether it's zoomed or not.
In order to transition between views using XAML, you must use the ViewStateManager to define VisualState elements. The template includes four visual states:
- FullScreenLandscape: Applies when the app is in full screen landscape mode. The application is designed for this layout, so you'll rarely require any specific changes for this state.
- Filled: Applies when the user has another application in Snapped view. For the sample application, there are no changes required for this state, either, although some applications might need specific markup for this state.
- FullScreenPortrait: Applies when the user has rotated the screen to portrait mode. You might find that you need to modify your application to make the best use of this layout (that is, a screen that is taller than it is wide).
- Snapped: Applies when the user has opened the application in Snapped view, taking up the smaller portion of a landscape screen. The Basic Page template provides different Back button and title styles for this mode. For the sample application, you will need to alter the layout to fit this view state.
TIP: You can certainly write your own code to effect view state changes. The VisualStateManager element and its children only applies to declarative view state changes-that is, to choices you make at design time that don't require any programming code.
Modifying Properties When State Changes
In order to modify properties when the view state changes, first find the VisualState element that corresponds to the new view state. Add a StoryBoard element if one doesn't already exist, and within the StoryBoard element, add an ObjectAnimationUsingKeyFrames element for each property you want to change because the application has changed to the new view state.
As attributes of the ObjectAnimationWithKeyFrames element, set the StoryBoard.TargetName and StoryBoard.TargetProperty attributes, indicating the name of the element and the name of the property you want to change.
Finally, within the ObjectAnimationWithKeyFrames element, create a DiscreteObjectKeyFrame element describing the time for the change (generally, 0 seconds) and the new value of the property, in the KeyTime and Value attributes. (As you can see, this is possibly the most complex and unintuitive means of indicating a property change possible.)
Below, you'll find markup which sets the Style property of the backButton element to the SnappedBackButtonStyle, when the view state changes to Snapped.
TIP: What if you need to add or remove controls? You can't, at least, not using this mechanism. Instead, set the Visibility property of the element. Create all the markup you'll ever need at design time, and show and hide things based on the view state.