WP7Contrib – Tombstoning Part I The View

Yes I know, that old chestnut what more could there be to say? Well quite a lot actually and my intentions are to do this as a two part blog post. Where we’ll cover off how to use the new tombstoning mechanism found in the WP7Contrib (WP7C).

But, hang on you said that WP7C already supports tombstoning as you provide an interface called IStorageService which is a wrapper for using Isolated Storage on the phone?
And, yes, that is correct normally we would have a bootstrapper and use Dependency Injection to setup the application scaffolding. However, this approach is only useful when you are looking to persist data that you have in the View Model, it’s simple and symmetrical allowing you to express your intentions clearly.

However, the Storage Service was designed to be used with properties which are observable ( INotifyProperyChanged) and databound in the UI either via Xaml or code behind. These properties are used to control and manipulate state and logic being processed by your VM. Cool, this works for data and it’s a trivial exercise to get this implemented as I will show you in the next post.

But what about the View?

Exactly, up until now in our projects we have exposed additional properties on the View Model to deal with View state. Its something that, Ollie and I have been meaning to refactor and recently we took on the challenge and the results make it a trivial exercise for you to add View state tombstoning into your app.

Let me explain, View state is purely about the status of the controls in the Visual Tree. This status has nothing directly to do with any data bound to the control.

Therefore, you’re not going to find tombstoning support for TextBox, CheckBox, PasswordBox, RadioButton or ToggleButton in the View state tombstoning. The reason for this is we assume you’re databinding to the IsChecked Dependency Property and the responsibility of managing the state lies with the View Model. You may be databinding directly to your model objects and I have no issues with this in certain cases, but in both of these cases we find that the state management and logic of the app is not the responsibility of the View.

The View state tombstoning supports Panorama, Pivot & ScrollViewer*. Thanks to composition we don’t need an explicit tombstoner for ListBox as the only state we are interested in saving is the scroll position handled by the ScrollViewer tombstoner. If you want to create a custom one then you can by implementing the ICanTombstone interface and register your new tombstoner.

* From Aug SL Toolkit Long List Selector uses a ScrollViewer

So, the tombstone support offered is very specific for example; when scrolling a list we want to remember what the ScrollViewer’s offset was; when panning either the Pivot or Panorama we want to remember which item you were viewing; and if you have a list in one of your Pivot or Panorama items we want to remember the offset is was well.

The implementation of the View state tombstoning is boiler plate so once you have copied and pasted the code below into you app your done! The View state classes can be found in WP7Contrib.View.Controls. Tombstoner so you will need a reference to WP7C.View.Controls.

To restore the view state wire up the loaded event and call RestoreState.

       this.Loaded += (sender, args) =>; this.RestoreState();

To persist the view state override the OnNavigatedFrom method and call PersistState.

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
       base.OnNavigatedFrom(e);
       this.PersistState();
}

Boom! Your done!

So, you may be asking why the RestoreState happens in the Loaded and not in the OnNavigatedTo method override. Well actually it started its life their, however when we wired in the original tombstoning we found that because our View Model was asynchronously loading data from a service into the View Model sometimes it had not finished by the time the OnNavigatedTo method was invoked. Therefore it lives in the Loaded event as we can pretty much guarantee that the controls will be bound to our properties exposed by the View Model. You may not want to have this level of complexity however I am pretty certain that you will want to have the flexibility of using asynchronous calls in either your View Model or the services that it uses.

The inspiration and tombstoning concepts can be found here in the TombstoneHelper developed by Matt Lacey. While I really like the conceptual idea that my pages should be able to automatically support tombstoning and it just happens automagically. The reality is that when using a pattern such as MVVM one of the principles we sign up for is Separation of Concern between the View and the View Model and because of this its conceptually simpler to allow each to only be responsible for there area of concern, View = UI, View Model = data.

The View state tombstoner would not be possible if it weren’t Colin Eberhardt and his amazing Linq to Visual Tree class.

Next I will cover off using the View Model state tombstoning and illustrate how you can combine both approaches to provide a complete tombstoning solution for your app.

Be Sociable, Share!

Tags: ,


Leave a Reply