In this second part of the picture gallery blog series we'll discuss how information is being passed between pages and how favorites are persisted to the phone's flash memory. If you haven't read the first part of this blog series, be sure to also check out the first part as well.
When navigating between pages we need a mechanism to tell the new page what it will be visualizing. There are two ways to achieve this. One is to pass information between pages as parts of the query string in the page’s Uri. This is a rather limited approach and in the Picture Gallery we will be using another option: PhoneApplicationService’s State dictionary.
Using the State dictionary has two benefits. First we have a ready-to-use mechanism of passing information around and second everything that is inside this dictionary (assuming it is serializable) will be written to the phone’s flash memory once the application is deactivated. The latter becomes handy when the user suspends the application by pressing the Windows hardware button. Once suspended, if the user continues using other apps for a while, there’s a pretty significant chance that the picture gallery will be tombstoned. When this happens, if our currently viewed model is not inside the State dictionary, it will not be restored! From that point on it’s easy to imagine a NullReferenceException slapping you in the face when your page gets resurrected from the grave but has no view model to work with. That said, the general pattern of passing state in the Picture Gallery goes like this:
- Every page, in its constructor method, uses the State to get the view model it knows how to visualize.
- Every page that can navigate to another page is required to put the necessary view model in the state dictionary before the user navigates to the new page. Back navigation is not handled in any way. The current view models remain in the state until they are overwritten.
At first glance there is an obvious problem with this. If every page puts its view model inside the State, wouldn’t that result in a memory leak? Normally it would, but in the case of the Picture Gallery there can always be only one instance of a particular view model type inside the State. Also, the view models that are inside the state should remain there until overwritten in order to be serialized when the application is suspended. Finally since they are very lightweight objects that only contain metadata for a particular photo, author or other object, having a few view models remaining in memory is not a real issue. Also the view models are implemented lazily, that is, they request information from the web service on demand. If you have a photo view model, it will only contain a URL for the image it represents and nothing else. Then if you get the Comments property, the view model will asynchronously download the comments and then notify the view via the INotifyPropertyChanged interface.
Saving and loading favorites
Saving favorites is a pretty common feature for many applications that display artistic content so it has a rightful place in the Picture Gallery app. Since our view models are very simple objects that contain only primitive types to store information their persistence is trivial.
To save our favorite view models we just use the DataContractSerializer provided by the Windows Phone environment. The DataContractSerializer works with classes that are marked with the [DataContract] attribute. Furthermore, all properties or fields that need to be serialized have to be marked with the [DataMember] attribute. Other members of the class are simply ignored. With these requirements in mind, we modify our view models to be marked with [DataContract] and [DataMember] and whenever the end-user saves or deletes a favorite we persist the currently saved favorites (stored in an observable collection) to the phone’s flash memory using an instance of the DataContractSerializer class.
In the next and final installment of this exciting blog series we will discuss how the Picture Gallery handles error conditions and how Rad Controls for Windows phone fit into the mix by making your life as an app developer easier.