About the Author

Danny is a Senior Software Engineer at InterKnowlogy in Carlsbad, CA. Danny began acquiring his expertise in software engineering at Neumont University in Salt Lake City, Utah where he graduated with a BSCS. Danny’s passion for technology has led him throughout the Microsoft Stack including .NET, C#, XAML, and F#. Danny has an expertise in NUI (The Natural User Interface) having built numerous multi-touch and gesture based interfaces for software applications across a broad spectrum of devices. Currently his passion includes building Windows Universal Apps and WPF Applications driven by gesture interaction using the Microsoft Kinect. Danny is an Alumnus Microsoft MVP for Windows Platform Development and speaks all over the country including That Conference, Spark Conference, and SoCal Code Camp. When not building beautiful software, Danny is an outdoors man and devoted husband and father. He loves to camp, hike and mountain bike. Follow him on twitter @dannydwarren

Session 5 of the WinRT Development Class – Search and Settings

WinRTWebBanner_JPEG

 

What a crazy session! We pulled through it like champs! Thank you everyone who attended. It was a blast and we are working with our sponsors to ensure future sessions go much smoother.

Session Resources

Next session will mark the half way point so don’t miss it! Kevin will be presenting about the Share Contract on Monday February 4th! It’s going to be great!

Overview of Sessions

The links below lead you to Meetup Events where you can RSVP. We look forward to seeing you at our next session!

1. Introductory Lecture (Nov 27th by Danny & Kevin)
2. Introduction to XAML and WinRT’s powerful Control Framework; (Dec 4th by Danny & Kevin Click here for the video recording)
3. Page-Navigation Model and Application Lifecycle (Jan 8th by Danny Click here for the video recording)
4. Fundamentals (Async/Await, WinRT API, Security) (Jan 15th by Kevin Click here for the video recording)
5. Settings and Search Contract (Jan 28th by Danny Click here for the video recording)
6. Share Contract (Feb 4th by Kevin)
7. Live Tiles and Background Tasks (March 18th by Kevin)
8. Orientation Handling and Proximity using Near Field Communication (NFC) (March 25th by Danny)
9. Introduction to ModelViewViewModel (MVVM) (April 8th by Danny)
10. InterKnowlogy’s WinRT MVVM Framework Session Part I/II(April 22nd by Kevin)
11. InterKnowlogy’s WinRT MVVM Framework Session Part II/II(May 6th by Danny)
12. Presentation of Hackathon Results + Certificate/Prize Giveaway(May 22nd by Danny and Kevin)

Session 3 of the WinRT Development Class – App Lifecycle and Navigation

WinRTWebBannerSmall_JPEG

What an excellent session! I know it’s been a little over a week, but I’m very grateful to all those who attended! For those of you who were not able to attend we have a video of the session! Please find the class resources and link to the video below.

Session 3 Resources

Overview of Sessions

The links below lead you to Meetup Events where you can RSVP. We look forward to seeing you at our next session!

1. Introductory Lecture (Nov 27th by Danny & Kevin)
2. Introduction to XAML and WinRT’s powerful Control Framework; (Dec 4th by Danny & Kevin Click here for the video recording)
3. Page-Navigation Model and Application Lifecycle (Jan 8th by Danny Click here for the video recording)
4. Fundamentals (Async/Await, WinRT API, Security) (Jan 15th by Kevin Click here for the video recording)
5. Settings and Search Contract (Jan 28th by Danny)
6. Share Contract (Feb 4th by Kevin)
7. Live Tiles and Background Tasks (March 18th by Kevin)
8. Orientation Handling and Proximity using Near Field Communication (NFC) (March 25th by Danny)
9. Introduction to ModelViewViewModel (MVVM) (April 8th by Danny)
10. InterKnowlogy’s WinRT MVVM Framework Session Part I/II(April 22nd by Kevin)
11. InterKnowlogy’s WinRT MVVM Framework Session Part II/II(May 6th by Danny)
12. Presentation of Hackathon Results + Certificate/Prize Giveaway(May 22nd by Danny and Kevin)

Session 1 & 2 of the WinRT Development Class – Introduction, XAML, and WinRT’s Control Framework

WinRTWebBannerSmall_JPEG

 

The first two sessions of the WinRT Development class were a great introduction to what Windows 8 WinRT development really is and to XAML development. We’re very excited about the future sessions and hope every developer will come learn with us about developing WinRT apps!

Session 1 Resources

Session 2 Resources

 

Overview of Sessions

The links below lead you to Meetup Events where you can RSVP. We look forward to seeing you at our next session!

1. Introductory Lecture (Nov 27th by Danny & Kevin)
2. Introduction to XAML and WinRT’s powerful Control Framework; (Dec 4th by Danny & Kevin Click here for the video recording)
3. Page-Navigation Model and Application Lifecycle (Jan 8th by Danny)
4. Fundamentals (Async/Await, WinRT API, Security) (Jan 15th by Kevin)
5. Settings and Search Contract (Jan 28th by Danny)
6. Share Contract (Feb 4th by Kevin)
7. Live Tiles and Background Tasks (March 18th by Kevin)
8. Orientation Handling and Proximity using Near Field Communication (NFC) (March 25th by Danny)
9. Introduction to ModelViewViewModel (MVVM) (April 8th by Danny)
10. InterKnowlogy’s WinRT MVVM Framework Session Part I/II(April 22nd by Kevin)
11. InterKnowlogy’s WinRT MVVM Framework Session Part II/II(May 6th by Danny)
12. Presentation of Hackathon Results + Certificate/Prize Giveaway(May 22nd by Danny and Kevin)

Development Environment for Windows 8

With the advent of Microsoft’s latest OS, a lot of people are asking how to get setup for developing Windows 8 applications. Here is a short post about getting a development environment for Windows 8 up and running.

Where to find Windows 8?

Full OEM

A full copy of Windows 8 can be purchased at http://www.newegg.com/Product/Product.aspx?Item=N82E16832416552. Be careful to only purchase the Windows 8 Pro version and not the Windows 8 version. Only Windows 8 Pro supports developing.

Upgrade

This is the preferred option.  Windows 8 is great OS. This option also guarantees the developer the best environment for developing for Windows 8. Anyone machine running Windows XP SP3, Vista, or Windows 7 can be upgraded. The upgrade cost is currently $40 (until Jan. 31st 2013) at http://windows.microsoft.com/en-US/windows/buy?ocid=GA8_O_WOL_DIS_ShopHP_FPP_Light for digital media. Developers can/need to create physical media from the digital media by using the Windows 7 USB/DVD download tool in order to create a bootable USB or DVD available at http://www.microsoftstore.com/store/msstore/html/pbPage.Help_Win7_usbdvd_dwnTool. The tool allows users to create a bootable DVD or USB. Typically the USB has been found to be the easiest. Physical upgrade media is also available at the same site for $70 (until Jan 31st 2013).

Evaluation Copy of Windows 8

The evaluation copy can be installed natively, in a virtual machine, or on a bootable VHD. The evaluation copy cannot be upgraded and is only good for 90 days. After 90 days Windows would need to be installed via a clean install. The evaluation copy can be found here http://msdn.microsoft.com/en-US/evalcenter/jj554510.aspx?wt.mc_id=MEC_132_1_4. The suggested route with the evaluation copy is to create a virtual machine or a bootable VHD. To learn how to create a bootable VHD read this article http://blogs.interknowlogy.com/2011/09/01/windows7bootablevhd/. To learn about creating a virtual machine read this article http://www.techspot.com/guides/503-windows-8-virtual-machine/. Please be aware that the virtual machine and bootable VHD methods only available in Windows 7 (Home Premium or higher).

Tools and Resources

Once Windows 8 is installed visit http://dev.windows.com and http://msdn.microsoft.com/en-US/windows/apps/br229516.aspx to download Visual Studio 2012 and other tools and resources for developing for Windows 8.

VNEXT Presentation: Building for the Future with Windows Phone & Windows 8

Here is the slide deck and sample code from the presentation I gave last night (8/14/2012).

I had such a great time presenting. vNext is an amazing group! Very intelligent developers and quite creative too. It was fun talking about ideas for apps and speculating about the future.

Feedback is always welcome. If there is something you wish I had presented on but didn’t or if I just spent too much time in slides please let me know. Thank you vNext for letting me come and present on this new and exciting topic! Always a pleasure!

Windows Phone 7.5 Isolated Storage for Complex Object Graphs

This post is somewhat related to my series WP7 Simplified. I have been writing the series based on an app codenamed LionHeart and just last night I was trying to get the PhoneDataProvider to save three (3) collections of complex objects. Up till now I’ve been regenerating my mock data each run. That’s OK until you want to start persisting data. Now that I’ve disabled the constant regen of data, I’ve uncovered a small mystery that confounded me for a few hours. So in hopes to save you some time here is what I found.

Basic Serialization Overview

Objects stored in IsolatedStorage are serialized. That means objects retrieved from IsolatedStorage are deserialized. IsolatedStorage uses the DataContractSerializer from WCF. I’m not sure if it’s the same, but that doesn’t matter right now. What that means is it relies on an opt-in pattern for objects to be serialized. Objects that are to be serialized but be adorned with the DataContract attribute and all properties that need to be serialized need to be public, have a getter and a setter, and be adorned with the DataMember attribute. That’s a lot of annoying attribute maintenance if you ask me. Luckily, Windows Phone 7 automatically assumes that each class is adorned with DataContract and all public properties with a getter and a setter are adorned with DataMember so you don’t have to messy up your class with the actual attributes. Cool! Thanks, Windows Phone! However not everything is free. Each each type that will be stored in IsolatedStorage MUST have a public paramerterless (default) constructor. If inheritance is used and there are properties of the base type where derived types might be stored then the KnownType attribute MUST be applied to the base type referenced for all derived types.

The Problem and Fix

Now into the problem I ran into. If you are missing KnownType attributes when calling IsolatedStorageSettings.ApplicationSettings.Save() a SerializationException will be thrown. This is actually good because it tells you what to fix. However, if one of the types is missing a parameterless constructor the Save method will not throw any exceptions. Why is this? Because serialization does not require the parameterless constructor, but deserialization does. So, one might expect an exception when deserializing that object from IsolatedStorage. Deserialization does fail but only throws a KeyNotFoundException. That is absolutely NOT helpful. So I scoured the internet and came across this post discussing manual serializing and deserializing. Figuring it was something to do with my objects failing to serialize or deserialize I used the two methods from the sample for Serialize and Deserialize on each collection of objects that I was about to save to IsolatedStorage. Sure enough I found that I was missing a parameterless constructor and deserialize was failing. Once I fixed my object everything saved just fine.

Serialize, Deserialize, and TestSerialization methods:

public class PhoneDataProvider : IDataProvider
{
	private static string Serialize(object objectToSerialize)
	{
		using (MemoryStream ms = new MemoryStream())
		{
			DataContractSerializer serializer = new DataContractSerializer(objectToSerialize.GetType());
			serializer.WriteObject(ms, objectToSerialize);
			ms.Position = 0;
	
			using (StreamReader reader = new StreamReader(ms))
			{
				return reader.ReadToEnd();
			}
		}
	}
	
	private static T Deserialize<T>(string jsonString)
	{
		using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
		{
			DataContractSerializer serializer = new DataContractSerializer(typeof(T));
			return (T)serializer.ReadObject(ms);
		}
	}
	
	private void TestSerialization<T>(T originalObject)
	{
		string serializedObject = Serialize(originalObject);
		T deserializedObject = Deserialize<T>(serializedObject);
	
		if (Equals(deserializedObject, default(T)))
		{
			throw new Exception();
		}
	}
}

Using TestSerialization:

public class PhoneDataProvider : IDataProvider
{
	public void SaveChanges()
	{
			#if DEBUG
			
			TestSerialization(_clients);
			TestSerialization(_sessionNotes);
			TestSerialization(_sessions);
			
			#endif
			
			SaveValue(CLIENTS_KEY, _clients);
			SaveValue(SESSION_NOTES_KEY, _sessionNotes);
			SaveValue(SESSIONS_KEY, _sessions);
	}
}

So now, only in DEBUG mode, each complex object graph is “validated” and then saved to IsolatedStorage. I love it when things finally work!

WP Simplified: Data Providers for Real vs. Mock Data

This post will bring closure to the framework components of my series WP Simplified. We’ll be covering, at very high level, how to architect data providers in Windows Phone 7.5 and a good pattern for supporting real and mock/design time data. I discuss storage options in a post about Tombstoning. Due to simplicity I’ve chosen to use IsolatedStorage for storage.

Object References

Let’s first discuss what the best approach for developing a data provider is. Understanding that each app is going to require a completely custom build data provider there is one rule that I feel very strongly about. That rule is that if you have a reference to an object that is stored in persistent storage you should not create a second reference to that object inside of the same app. In other words, when you ask a data provider for an object it should always return the same object and not a different instance. We ran into a huge problem with modifying the incorrect copy of an object due to the pattern we were following for navigation. I mentioned this problem in WP7 Simplified: CoreApplicationService (Navigation) under the section titled Lesson #1: Centralize Data.

So, what’s the solution? Cache objects in memory for the lifetime of the app and always return the same reference to an object from the cache if it exists or create a reference to an object and store it in cache. We found that using ReadOnlyObservableCollection<T> allowed us to be pretty flexible. In phone apps users are typically viewing lists of data or data from a list and they want to know immediately if new data is available. By using Observable Collections the list is automatically updated when new data is available. The reason for use ReadOnlyObservableCollections is so the data provider can hand off a collection to a VM and the VM will not be able to add any new items to that collection directly. Instead the VM must utilize the data provider for CRUD actions on the collection.

Data Provider in Lion Heart

We use Initialize rather than the Constructor in our PhoneDataProvider for data setup. This allowed us to think in one pattern for VMs and DataProviders rather than jumping around and forgetting when data is setup and where that logic lives. Until Initialize is called the data provider is not useful and will throw errors.

public class PhoneDataProvider : IDataProvider
{
	private static readonly string CLIENTS_KEY = "CLIENTS_KEY";
	private static readonly string SESSION_NOTES_KEY = "SESSION_NOTES_KEY";
	private static readonly string SESSIONS_KEY = "SESSIONS_KEY";

	private bool _isInitialized;
	private ObservableCollection<Client> _clients;
	private ObservableCollection<SessionNotes> _sessionNotes;
	private ObservableCollection<Session> _sessions;
	private ReadOnlyObservableCollection<Client> _clientsReadOnly;
	private ReadOnlyObservableCollection<SessionNotes> _sessionNotesReadOnly;
	private ReadOnlyObservableCollection<Session> _sessionsReadOnly;

	public void Initialize()
	{
		if (_isInitialized)
		{
			return;
		}

		if (!RetrieveValue(CLIENTS_KEY, out _clients))
		{
			_clients = new ObservableCollection<Client>();
		}
		if (!RetrieveValue(SESSION_NOTES_KEY, out _sessionNotes))
		{
			_sessionNotes = new ObservableCollection<SessionNotes>();
		}
		if (!RetrieveValue(SESSIONS_KEY, out _sessions))
		{
			_sessions = new ObservableCollection<Session>();
		}

		SaveChanges();
		_isInitialized = true;
	}
	
	private bool RetrieveValue<T>(string key, out T value)
	{
		return IsolatedStorageSettings.ApplicationSettings.TryGetValue(key, out value);
	}
	
	public void SaveChanges()
	{
		SaveValue(CLIENTS_KEY, _clients);
		SaveValue(SESSION_NOTES_KEY, _sessionNotes);
		SaveValue(SESSIONS_KEY, _sessions);
	
		Save();
	}
	
	private void SaveValue<T>(string key, T value)
	{
		IsolatedStorageSettings.ApplicationSettings[key] = value;
	}
}

A few important things to note here.

  1. Only Initialize if the data provider is not initialized.
  2. Retrieve collections from IsolatedStorage or create them if they do not exist. These collections are now the cache of objects that should be queried for the rest of the app lifetime.
  3. Call SaveChanges to persist any newly created collections. (This may or may not really be necessary.)

When a VM requires a collection of objects it must request that collection via a method. In LionHeart we will use Client as an example. To get the collection of Clients from the data provider the method GetClients must be used.

public class PhoneDataProvider : IDataProvider
{
	public ReadOnlyObservableCollection<Client> GetClients()
	{
		if (_clientsReadOnly == null)
		{
			_clientsReadOnly = new ReadOnlyObservableCollection<Client>(_clients);
		}
		return _clientsReadOnly;
	}
}

When a new object is created and needs to be added to a collection expose a method to handle this functionality. We do this with a new Client via the AddClient method.

public class PhoneDataProvider : IDataProvider
{
	public void AddClient(Client newClient)
	{
		if (newClient != null)
		{
			_clients.Add(newClient);
			SaveChanges();
		}
	}
}

Deleting an object should be handled the same way as add. LionHeart has no need for deleting so I don’t have any example to show.

Finally, if an existing object is modified the only action required is to call SaveChanges.

public class PhoneDataProvider : IDataProvider
{
	public void SaveChanges()
	{
		SaveValue(CLIENTS_KEY, _clients);
		SaveValue(SESSION_NOTES_KEY, _sessionNotes);
		SaveValue(SESSIONS_KEY, _sessions);
	
		Save();
	}
}

When modifying objects and calling SaveChanges on the data provider one might think of Entity Framework or LINQ to SQL. Those frameworks were actually used as inspiration for the data provider pattern used. It is important to know that LINQ to SQL is supported in Windows Phone 7.5 and I shamefully have had no time to look into using it. I fully admit that the data provider architecture in LionHeart could and probably be improved.

Real (Production) vs. Mock (Design) Data Providers

I had some help from Bryan Coon and Tim Askins coming up with a pattern that would easily support using Blend with mock data without the need for a bunch of crazy garbage code. In the first code snippet shown you’ll notice PhoneDataProvider implements the interface IDataProvider.

public interface IDataProvider
{
	void Initialize();
	void SaveChanges();
	void AddClient(Client newClient);
	void AddSessionNotes(SessionNotes newSessionNotes);
	void AddSession(Session newSession);
	Client GetClient(Guid clientId);
	Session GetSession(Guid sessionId);
	SessionNotes GetSessionNotes(Guid sessionNotesId);
	ReadOnlyObservableCollection<Client> GetClients();
	ReadOnlyObservableCollection<SessionNotes> GetSessionNotes();
	ReadOnlyObservableCollection<Session> GetSessions();
	Session GetSessionForSessionNotes(Guid sessionNotesId);
}

By doing this we open up the opportunity to use the Locator pattern. LionHeart includes DataProviderLocator which simply chooses which IDataProvider to hand out.

public class DataProviderLocator
{
	private static IDataProvider _dataProvider;
	public static IDataProvider DataProvider
	{
		get
		{
			if (_dataProvider == null)
			{
				if (DesignerProperties.IsInDesignTool)
				{
					_dataProvider = MockDataProvider.Instance;
				}
				else
				{
					_dataProvider = PhoneDataProvider.Instance;
				}
				_dataProvider.Initialize();
			}
			return _dataProvider;
		}
	}
}

In this case only two IDataProvider implementers exist: PhoneDataProvider and MockDataProvider. If the app is in a design tool then the MockDataProvider is used otherwise the PhoneDataProvider is used.

Now the only weird part, and I’m still trying to find a better way to do this, is setting up VMs for mock data. Usually the Initialize method of a VM is called to set it up with data, however Initialized will never be called in design tool. In this case we still must modify the VM we desire to use in Blend by adding a query to the DataProvider in the Constructor of the VM.

public class ClientPageVM : PageViewModel
{
	public ClientPageVM()
	{
		if (DesignerProperties.IsInDesignTool)
		{
			InitializeData(DataProviderLocator.DataProvider.GetClients().First().Id);
		}
	}
	
	private void InitializeData(Guid clientId)
	{
		Client = ViewModelFactory.CreateClientVM(DataProviderLocator.DataProvider.GetClient(clientId));
		...
	}
}

This code will only be run when the app is in a design tool so it’s safe to leave in. One could argue that it should be optimized out in release mode and I think that would not be a bad idea.

Something interesting to note here is that the InitializeData method is used as a single point of entry whether or not the app is in a design tool or not. There is a huge benefit to this. Reduced duplicated code. If the way the VM handles the client id changes, the updates only need to be applied in one location. DONE!

Conclusion

This post ends coverage of Framework Elements in LionHeart. The other cool part about finishing this post is the next step is to provide a project template that will provide all the Framework Elements discussed in this series automatically.

WP7 Simplified: PageViewModel, ViewBase, and Using CoreApplicationService

In this post continuing my series WP7 Simplified we’ll be covering the PageViewModel class. This ViewModel (VM) hides all of the complicated wiring up that is necessary to work with ViewBase as mentioned in my post WP7 Simplified: CoreApplicationService (Navigation). PageViewModel is an abstract class that acts as the base class for all VMs backing Views (aka Pages). The three key parts to this class are: Initialize, Uninitialize, and hooking into the CoreApplicationService (CAS).

Initialize

ViewModels need to be built up based on navigation parameters in Windows Phone. Because of this it is more flexible to use an Initialize and Uninitialize vs. Constructor and Dispose pattern. Derived VMs can be defined as the DataContext in the XAML of Views that inherit from ViewBase.

<Views:ViewBase x:Class="LionHeart.UI.Phone.Views.HomeView"
				… >
	<Views:ViewBase.DataContext>
		<vms:HomeVM />
	</Views:ViewBase.DataContext>
</Views:ViewBase>

When the view is navigated to the OnNavigatedTo method is called. If this view has a constructed PageViewModel as the DataContext it is initialized here.

public class ViewBase : PhoneApplicationPage
{
	public PageViewModel PageViewModel { get { return DataContext as PageViewModel; } }

	protected override void OnNavigatedTo(NavigationEventArgs e)
	{
		if (PageViewModel != null)
		{
			var parameters = e.NavigationMode == NavigationMode.Back ? null : NavigationContext.QueryString;
			PageViewModel.Initialize(parameters);
		}
		base.OnNavigatedTo(e);
	}
}

Notice that the NavigationContext.QueryString is only passed into Initialize if this navigation is NavigationMode.New. This is important. When the user navigates forward in the app the NavigationMode will be New. In this case the NavigationContext.QueryString is required because the VM has never been initialized before and has no data. However, if the NavigationMode is Back then this VM has already been initialized with data so we only need to initialize the VM without data.

public abstract class PageViewModel : ViewModelBase
{
	public void Initialize(IDictionary<string, string> parameters = null)
	{
		InitilizeAlways();
		if (!IsInitialized)
		{
			bool isLaunching;
			CoreApplicationService.TryRetrieveTombstoningValue(
				CoreApplicationService.IS_LAUNCHING_KEY, out isLaunching);
			if (parameters != null &&
				(parameters.ContainsKey(CoreApplicationService.IS_RUNNING_KEY) || isLaunching))
			{
				InitializeFromNavigation(parameters);
			}
			else if (!HasState)
			{
				InitializeFromActivation();
			}
			HasState = true;
			IsInitialized = true;
		}
	}
	
	protected virtual void InitilizeAlways()
	{
		SubscribeGlobalHandlers();
	}

	protected virtual void InitializeFromNavigation(IDictionary<string, string> parameters) { }

	protected virtual void InitializeFromActivation() { }
	
	protected virtual void InitializeWithState() { }
	
	protected virtual void SubscribeGlobalHandlers()
	{
		if (!IsSubscribed)
		{
			CoreApplicationService.Deactivated += DeactivatedHandler;
			CoreApplicationService.Closing += ClosingHandler;
			IsSubscribed = true;
		}
	}
}

Inside of Initialize there are a few actions to perform. The first is to initialize anything that needs to always be initialized via the virtual method InitializeAlways. Generally nothing should be done here except hookup Global event handlers with the virtual method SubscribeGlobalHandlers. SubscribeGlobalHandlers is always called inside of InitializeAlways however, the code inside is only run if the property IsSubscribed is false. IsSubscribed is false if the VM has not been initialized or if it has been torn down.

After InitializeAlways a check is performed to know if the VM is Initialized or not. If it is not then execution continues. The next check is to discover if the VM is being initialized because it the app was launched or from some other action while the app was running. The launched indicator is set in the CAS when it is initialized. The first VM to be initialized is responsible for removing this key from the Tombstoning values.

public class CoreApplicationService
{
	public void Initialize(PhoneApplicationFrame frame, bool isLaunching)
	{
		…
		StoreTombstoningValue(IS_LAUNCHING_KEY, isLaunching);
	}
}

The is running key is set each time the CoreApplicationService.Navigate method is called. If the VM is being initialized from launching or running then the parameters dictionary is passed to the virtual method InitializeFromNavigation. This method would be overridden by VMs that need data from the parameters, which is the NavigationContext.QueryString dictionary. If this method was called a few things can be inferred. The first is that this is a new, or forward navigation and this VM has never been initialized before meaning it has no state.

If the VM is not initializing from launching or running then it is initializing from deactivation. When coming from deactivation there are two possibilities: State is preserved or state was disposed. The VM uses the HasState property to know if state exists. This property is set to true at the end of Initialize and is never set to false. The only time the property would be false is if the VM was newly constructed and not yet initialized. If HasState is true then the virtual method InitializeWithState is called. Here is where we would do very very minimal code to refresh data that could have changed since deactivation. Usually, no work should be done in this method unless absolutely necessary. Fast Application Switching relies on as little code being run as possible when state has been preserved. If HasState is false then the virtual method InitializeFromActivation is called. When this method is called we know that no state exists and we need to access Tombstoning values through the CAS.

Just before exiting Initialize the HasState and IsInitialized properties are both set to true. At this point the VM is initialized and ready to go. If data needs to be pulled from web servers or other long running tasks during initialization make sure that the work is done async and that a busy indicator and message is used in place of the missing data. This is better than showing a blank page because most users will think a blank page is a broken page. Also, please cache data when possible. No need to store the entire web on the phone, but don’t make the user wait to see data every time the app is loaded. This is a huge complaint of mine when I use apps that display RSS feeds and each time I load the app the entire feed must be pulled from the server before I can see the articles I was reading a few minutes prior.

Uninitialize

There are three different time when the VM should be uninitialized: Navigating forward to a new view or out of the app, navigating backward, and when the view is removed from the navigation back stack. The VM is notified about all three of these cases by the ViewBase class.

public class ViewBase : PhoneApplicationPage
{
	protected override void OnNavigatedFrom(NavigationEventArgs e)
	{
		if (PageViewModel != null)
		{
			PageViewModel.Uninitialize(e.NavigationMode == NavigationMode.Back);
		}
		base.OnNavigatedFrom(e);
	}
	
	protected override void OnRemovedFromJournal(JournalEntryRemovedEventArgs e)
	{
		if (PageViewModel != null)
		{
			PageViewModel.Uninitialize(true);
		}
		base.OnRemovedFromJournal(e);
	}
}

The OnNavigatedFrom method is used to indicate navigation forward or backward events from this view. If the navigation is a back navigation then indicate to Uninitialize that a tear down is requested. The OnRemovedFromJournal method indicates that the view has been removed from the back stack and will not be used again. Uninitialize is immediately called with the tear down flag.

A question to ask here is should the VM always be uninitialized when it’s not in use? Or should it just have a pause setting? In this approach uninitializing the VM is always desired when it is not in use, but tearing down the VM is not. Tear down means the VM will never be used again, essentially it’s the VM dispose method without actually using the dispose pattern.

public abstract class PageViewModel : ViewModelBase
{
	public void Uninitialize(bool isTearDown = false)
	{
		UninitializeAlways();
		if (isTearDown)
		{
			UninitializeTearDown();
		}
		IsInitialized = false;
	}
	
	protected virtual void UninitializeAlways() { }
	
	protected virtual void UninitializeTearDown()
	{
		UnsubscribeGlobalHandlers();
	}

	protected virtual void UnsubscribeGlobalHandlers()
	{
		if (IsSubscribed)
		{
			CoreApplicationService.Deactivated -= DeactivatedHandler;
			CoreApplicationService.Closing -= ClosingHandler;
			IsSubscribed = false;
		}
	}
}

Uninitialize first calls the UnitializeAlways virtual method. Work done in UninitializeAlways should be things like pausing media elements, timers, and web service queries. Also, unhooking any handlers that should not be handled while the view is not in use. It’s important to know that views that are in the back stack still run code. They are not dormant or prevented from executing code, therefore any handlers that could cause code to run should generally be disabled. A possible candidate to ignore this might be a live feed that is expected to continue updating even while not on that view. Performance and battery life and the two reasons for this rule.

After UninitializeAlways if the isTearDown argument is true then the UninitializeTearDown virtual method is called. This method should be used to clean up anything on the page that needs to be disposed of, closed, etc. UninitializeTearDown is responsible for calling the virtual method UnsubscribeGlobalHandlers which simply unsubscribes from events such as app deactivating, closing, and error notifications. Nice and straight forward.

At the end of Uninitialize the property IsInitialized is set to false. There is no need to if the VM was torn down or not because a torn down VM will never be used again.

Integrating with the CoreApplicationService

The CAS is available as a singleton anywhere in the app, but we have found it nice to have a simple property in the VM to call. This also aids in replacing the CAS if needed with something else. As you saw above in the SubscribeGlobalHandlers method the VM subscribes to the Closing and Deactivated events on the CAS. These events are also not unsubscribed to unless the VM is being torn down. When either of these events are raised by the app the CAS receives then and passes them on to whom ever desires them, in this case the VM cares. The PageViewModel then calls a virtual method related to the event that was raised. If the Closing event is raised the PageViewModel calls the related virtual method Close. If the Deactivated event is raised the PageViewModel calls the virtual method Deactivate. This just aids in exposing methods and events that should be used in almost every VM that inherits from PageViewModel. The argument was proposed to make the methods abstract forcing derived types to implement the methods, but was eventually lost to keep them virtual and hope the developer is responsible and thinks through the flow of data and the app.

public abstract class PageViewModel : ViewModelBase
{
	protected CoreApplicationService CoreApplicationService
	{
		[DebuggerStepThrough]
		get { return CoreApplicationService.Instance; }
	}
	
	protected virtual void Deactivate()
	{
	}
	
	private void DeactivatedHandler(object sender, EventArgs e)
	{
		Deactivate();
	}
	
	protected virtual void Close()
	{
	}
	
	private void ClosingHandler(object sender, EventArgs e)
	{
		Close();
	}
}

The Close method is called when the user uses the back button of the phone to leave the app. In this method all data that needs to be persisted for future runs of the application need to be saved. Data that is transient like form data can be ignored.

The Deactivated method is called when the user hits the Windows logo button, or touches a notification that opens another app such as an SMS notification opens the Messaging app. This happens a lot more often than Close and needs special attention in each VM that is in the back stack or in use when called. In this method all persistent data needs to be saved in persistent storage and all transient data such as form data needs to be stored in transient storage. More information about the difference between persistent and transient storage and what data goes where read my post Windows Phone 7 – Tombstoning. Use the CAS to store transient data with the StoreTombstoningValue method.

public class CoreApplicationService
{
	public void StoreTombstoningValue(string key, object value)
	{
		PhoneApplicationService.Current.State[key] = value;
	}
}

In my experience with apps in the market place this is one area where most of them are only OK. I could spend hours discussing proper ways to handle app lifecycle and data flow, but I will spare you in this post.

Conclusion

Armed with everything you’ve learned here and in previous posts about the CAS you’re ready to start your very own MVVM Windows Phone application. App ideas, of course, must be supplied by your own creative juices, but there’s no shame in copying an idea for the purposes of learning. This post also brings us one post closer to having complete coverage of the Framework Components introduced in LionHeart.

Code Camp: Windows Phone 7.5 Simplified

First off thank you to everyone who attended my session at code camp. I hope you learned something new! I’d love to get feedback on how you felt the presentation went. Please leave me some comments here or shoot me an email or whatever.

In this session I used an app codenamed LionHeart to help explain the concepts and framework I presented. To learn more about the framework I have a blog series named Simplifying the Windows Phone Development Experience! Codename: LionHeart. In this series I go in much more depth about the same concepts I presented on.

Please note the source code release does not have fully completed app however, the framework used in the app is stable and the API’s are almost locked down.

When the framework is complete it will be available in Project Template form. This will allow you to easily start a new Windows Phone project with all of the boring boiler plate work completed for you.

Presentation Slide Deck

Source Code: LionHeart (codecamp release)

Cheers! And Happy Coding!

WP7 Simplified: CoreApplicationService (Tombstoning)

This post brings closure to coverage of the CoreApplicationService (CAS) in this series titled WP7 Simplified. The final topic to cover is how the CAS handles tombstoning. Before getting into that let’s discuss what tombstoning is first. There are a couple of different terms to be familiar with that all refer to the tombstoning process: App Deactivation, Fast Application Switching, Tombstoning.

App Deactivation

When ever a user navigates leaving the app, except when they use the back button to close the app, the app is deactivated. All of the application state is stored in memory and app execution has 10 seconds to pause (Read the very last caution in the documentation). During deactivation it is important to store any transient and persistent state/data. From this state the application can be activated without losing any state in which case little if any state needs to be restored because the OS didn’t dispose of any part of the app state. The app could also be tombstoned which means that all state will need to be restored, but the application can still be activated. Finally the app might be completely closed by the OS thus requiring a fresh start.

Fast Application Switching

When an app is activating and the OS preserved state, the app should not attempt to do a full state restore, but instead should leverage the fact that the OS preserved the app’s previous state.

Tombstoning

If an app is tombstoned it means that all app state has been removed from the OS memory. This is why it is important for developers to store app state in transient or persistent data stores during app deactivation. When an app is activated from being tombstoned it should appear in the exact same state it was in before the user deactivated the app. It should also look the same as if the app had utilized Fast Application Switching.

For a much better explanation of these topics and some coverage of the difference between what persistent and transient data stores are available in Windows Phone please read my post Windows Phone 7 – Tombstoning.

Handling Tombstoning in CoreApplicationService

In the CAS only transient data is handled. We use DataProviders for persistent data. When deciding what transient data needs to be stored for tombstoning remember that we need to be able to restore the app during activation to the exact same state it was left in. Think of Leave No Trace from Boy Scouts and camping, we don’t want to leave any trace that the app was ever deactivated or tombstoned. Also, keep in mind when storing full objects that the object reference after retrieving a tombstoned value will be different than the object reference that was stored. If the reference needs to be the same the object should be stored in a persistent data store that should hand out the same reference for that object each time it is requested. We store values for tombstoning with the CAS using the following API.

public void StoreTombstoningValue(string key, object value)
{
	PhoneApplicationService.Current.State[key] = value;
}

public bool TryRetrieveTombstoningValue<T>(string key, out T value, bool clearKey = false)
{
	object tempObj;
	var exists = PhoneApplicationService.Current.State.TryGetValue(key, out tempObj) && tempObj is T;
	value = exists ? (T)tempObj : default(T);

	if (clearKey)
	{
		ClearTombstoningValue(key);
	}

	return exists;
}

public void RemoveTombstoningValue(string key)
{
	PhoneApplicationService.Current.State.Remove(key);
}

Store Tombstoning Value

Windows Phone provides developers with the PhoneApplication.Current.State dictionary which will survive as long as the app is not closed. Here is where we store all transient data.

Try Retrieve Tombstoning Value<T>

When retrieving a value we wanted to streamline the experience. Thus, this method is generic and does all the checks and casts each time a value is requested. It reports weather the value was found and cast correctly. It optionally takes in a parameter indicating to clear the value out of the State dictionary.

Remove Tombstoning Value

After retrieving a tombstoning value for the last time it should be removed to decrease memory usage.

Quick Tip of What to Store for Tombstoning

As much as possible only store object Id’s instead of the full objects. Even if at the moment the reference to that object doesn’t matter it may matter down the road. The naming of these methods is also very important. It is strongly suggested to not use the State dictionary to store objects during navigation. While it is true that a full object can be stored in the State dictionary before navigation for the next page to access after navigation, the object references are different because the State dictionary serializes and then deserializes all objects being stored then retrieved. This fact hurt one of our last projects. Once we had a grip on this principle we were OK, but until then bug after bug would manifest and they were difficult to track down.

Conclusion

Nothing super fancy this time. The motivation to include this functionality in the CAS was the constant repetition of the code in TryRetrieveTombstoningValue<T>(). It has helped clean up our code base quite a bit. This post also concludes code coverage of the CAS. The CAS is a very key component to any Windows Phone development. We’re excited to hear how you use it or how the principles discussed around it have helped you. Leave some comments to let us know. Next in the series we will be covering PageViewModel which works closely with ViewBase which we discussed in the previous post of this series WP7 Simplified: CoreApplicationService (Navigation).