An easy way to save state in Silverlight and Windows Phone7

In many cases you need to save some state in your application. In Silverlight the best way to do this is to write to IsolatedStorage. After writing the same code many times for saving different types of objects to IsolatedStorage I started to look for a simpler/more generic way of doing it, and came up with a solution which makes me do like this:

//Write any object to IsolatedStorage
IsolatedStorageManager.WriteObjectToFile("aFileName",anyObject);

//Read any object back from IsolatedStorage
var objectFromFile = IsolatedStorageManager.ReadObjectFromFile<AnyClass>("aFileName");

This makes it very easy to write whatever object to IsolatedStorage. Below you can find my implementation of the IsolatedStorageManager

using System.IO;
using System.IO.IsolatedStorage;
using System.Text;

namespace IsolatedStorageSample
{
 public static class IsolatedStorageManager
 {
 public static void WriteObjectToFile<T>(string filename, T data)
 {
 string xml = Serialization.Serialize<T>(data);
 IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication();
 using (IsolatedStorageFileStream writer = file.CreateFile(filename))
 {
 byte[] content = Encoding.UTF8.GetBytes(xml);
 writer.Write(content, 0, content.Length);
 writer.Close();
 }
 }

 public static T ReadObjectFromFile<T>(string filename)
 {
 string xml = null;
 IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication();
 using (IsolatedStorageFileStream stream = file.OpenFile(filename, FileMode.Open))
 {
 using (StreamReader reader = new StreamReader(stream))
 {
 xml = reader.ReadToEnd();
 }
 }
 return Serialization.Deserialize<T>(xml);
 }
 }
}

The IsolatedStorageManager class depends on a class named Serialization which looks like this:

using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;

namespace IsolatedStorageSample
{
 public static class Serialization
 {
 public static string Serialize<T>(T objectToSerialize)
 {
 if (objectToSerialize == null)
 return null;
 using (MemoryStream ms = new MemoryStream())
 {
 DataContractJsonSerializer serializer = new DataContractJsonSerializer(objectToSerialize.GetType());

 serializer.WriteObject(ms, objectToSerialize);
 ms.Position = 0;

 using (StreamReader reader = new StreamReader(ms))
 {
 return reader.ReadToEnd();
 }
 }
 }

 public static T Deserialize<T>(string json)
 {
 if (string.IsNullOrEmpty(json))
 return default(T);

 DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
 T obj = (T)serializer.ReadObject(new MemoryStream(Encoding.Unicode.GetBytes(json)));
 return obj;
 }
 }
}

In order to get this to compile you need to add a reference to System.ServiceModel.Web

This code works great in both regular silverlight and in windows phone 7.

AutoCompleteBox in Windows Phone 7

Download sample source code

Windows phone 7 contains built in support for word prediction when a user types something in a TextBox. To enable this in your Textbox you have to set the InputScope to “Text” or “Chat”. If you create a TextBox like this:

<TextBox InputScope="Text" />

And starts to enter something in the TextBox you will see suggested words above the keyboard like you see below.

This is fine, and in many cases just what you need. But say for example you have an input field where you want your users to enter their favorite sport. Using InputScope Text or Chat is not the best option. If a user starts to enter “So” he will get a lots of words having nothing to do with sport – Doc, Six, Social, Society. The word “Soccer” which is the word the user most likely meant is not even on the screen, you will have to scroll to see it.

A solution to this could be to use a ComboBox (at least it could be a solution if it had been available for wp7), but in this case you have to define every sport you can think of when you write the application. But what if someone try to enter “Frisbee Golf” as their favorite sport. This is most likely not the first sport you think of when you sit down and make a list of sports, but it’s still someones favorite sport.

This is where the AutoCompleteBox from the Silverlight 3 toolkit is perfect. You can define all the sports you can think of. The user can select on of the already defined sports by just enter the first letters of the sport. If hes favorite sport is something you didn’t thought of, he can still enter it (but of course he wont get auto competition for that )

How to add an AutoCompleteBox to your wp7 application

  1. Add a reference to System.Windows.Controls.Input.dll (you have to browse for it – you find it where you installed the silverlight 3 toolkit) It is very important that you use the dll from the Silverlight 3 toolkit, as Silverlight 4 is not supported on Windows Phone 7.
  2. Add an AutoCompleteBox to your Xaml code and bind it to a list of words (a list of sports in my case). At this time the AutoCompleteBox works, but it doesn’t look good, as it is not styled like the other windows phone 7 controls. It also isn’t very touch friendly as the words in the list has to little space between the lines.
  3. Style the AutoCompleteBox to look like a wp7 control. See my sample code. The style is to long to include here.
  4. The control now looks good and is working. There is only one problem. If you select a word (a sport) from the list, the popup is not closed before you select it again. I read somewhere that this is a bug in wp7 and has nothing to do with the AutoCompleBox, but I can’t find it again, so I’m not 100% sure. Anyhow I have a really simple fix for this. On the SelectionChanged event I set focus to another control, this is normally what you want to do anyway. This closes the popup and the control works perfect.

Here you can see the final result both with the dark and the light theme

I have to thank Indrajit Chakrabarty for all help I got when I struggled with this. Blog: http://indyfromoz.wordpress.com/ Twitter: http://twitter.com/indyfromoz

Download sample code here