App tombstoning presents a new challenge for developers moving to the Windows Phone platform. As the complexity of your app increases, so too does the task of preserving your app’s transient and persistent state.
For this chapter, I have created an automatic state preservation system, which you are free to use. I intend to continue to refine and integrate it into the open source Calcium project.
The system presented in this section allows you to register properties for state preservation using a custom attribute. In addition, there is an API that uses lambda expressions for registering properties with nonpublic accessors and fields.
Using the system involves registering a property so that it is automatically saved and restored after tombstoning. This is done by decorating the property with the custom Stateful
attribute, as shown in the following example:
[Stateful(ApplicationStateType.Persistent)]
public int SomeProperty { get; set; }
The Stateful
attribute receives an ApplicationStateType
value, which indicates the type of state persistency that the property requires. ApplicationStateType
enum has the following two values:
Persistent—State is saved to isolated storage.
Transient—State is saved to the PhoneApplicationService.Current.State
.
The attribute-based approach is the simplest way for preserving the state of a property. Yet, to register fields or inject custom logic, the ViewModelBase
class also provides the methods shown in Table 28.2.
The eBay Search example from the Chapter 27, “Communicating with Network Services,” has been augmented to demonstrate the use of the state preservation system.
A SearchCount
property has been added to the new EbaySearchStateViewModel
(replacing the EbaySearchViewModel
) to demonstrate the State
attribute. This property is incremented each time a search takes place. It is preserved in isolated storage by using the Stateful
attribute, as shown in the following excerpt:
[Stateful(ApplicationStateType.Persistent)]
public int SearchCount { get; set; }
When the viewmodel is instantiated, the ViewModelBase
class identifies all properties that have been decorated with the attribute and registers them with a custom ViewState
class.
Additionally, within the viewmodel’s constructor there now exists various state registration statements. The first, shown in the following excerpt, registers the SearchText
property for transient state preservation:
RegisterStatefulProperty(ApplicationStateType.Transient, () => SearchText);
A lambda expression is used to identify the property. As part of this call, the expression is deconstructed to determine the name of the property and to create the property accessor (get and set) delegates, which are used to retrieve and set the SearchText
property during state preservation operations. If the app is deactivated, the SearchText
property (and any other registered transient state properties) are placed in the PhoneApplicationService.State
dictionary and reinstated if and when the app is reactivated.
In the following example, the Items
collection is registered for transient state preservation:
RegisterStatefulProperty(
ApplicationStateType.Transient, () => Items, x => Items = x);
Persisting an object to isolated storage works in the same way; however, we specify that the value is to be placed in persistent storage using the Persistent enum value, as shown:
RegisterStatefulProperty(
ApplicationStateType.Persistent, () => SearchCount);
18.217.164.143