Friday, 24 August 2012

A new pattern for Win8 ApplicationViewState handling

While trying to port our app Bridge Stenographer I was faced with the problem of supporting the new ViewStates in Windows 8.

I didn’t really like the idea of having a bunch of duplicate controls on my UI that I hid.

I didn’t really like the idea of having a frame that I navigated to a completely separate set of controls.

And I really didn’t like the messy syntax for managing view states with the VisualStateManager, particularly in light of my previous experiences of Visual States never doing what you expect.

So here’s my idea:

First, in the Common folder, modify LayoutAwarePage.cs to make the ObservableDictionary available to the rest of the classes by making it public (or protected).

Set up bindings in your DefaultView model, labelled with keys that define the states you require.  So for instance, I need to move some items from one grid location to another based on my state changes.

DefaultViewModel["keyboardRow"] = 2;
DefaultViewModel["keyboardColumn"] = 1;
DefaultViewModel["keyboardMaxWdith"] = 465;
_fullpage = DefaultViewModel;

Where _fullpage is defined as (sorry about Wdith typo above.  How to edit in LiveWriter???)

private IObservableMap<string, object> _fullpage;
private IObservableMap<string, object> _snapped;

Then in my constructor I also add the _snapped object:

_snapped = new ObservableDictionary<string, object>;
_snapped["keyboardMaxWidth"] = 300;
// etc...

Then in my code, I simply bind to

<somecontrol MaxWidth="{Binding DefaultViewModel[keyboardMaxWidth]}" />

And swap the DefaultViewModel in response to the SizeChanged event on the page:

void BiddingPage_SizeChanged(object sender, SizeChangedEventArgs e)
switch (ApplicationView.Value)
case ApplicationViewState.Snapped:
DefaultViewModel = _snapped;
DefaultViewModel = _fullpage;

Hey Presto!  New layout.
I was looking for a way to do this declaratively in the XAML, by creating the Observable collections there, but alas, haven’t yet figured out how to do that.

No comments:

Post a Comment