Logo
HOW TO
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
 
 
Windows Phone

Windows Phone 7 Programming Model : Application Data Persistence

11/30/2012 6:29:00 PM
Saving data to the file system is a necessity for most real applications. On Windows Phone 7, each application can access an isolated file system to read and write data that is only accessible to that application. This means that applications cannot share data with each other via the file system. It also means that one application cannot access or overwrite data from another application in the file system.

There are several namespaces related to data persistence that are available on Windows Phone 7. These namespaces include the following:

  • System.IO: Provides access to base Stream, StreamWriter, and StreamReader classes.

  • System.IO.IsolatedStorage: Provides access to Isolated Storage.

  • System.Runtime.Serialization: Must add a reference to System.Runtime.Serialization assembly.

  • System.Xml: Provides access to XMLReader stream class, as well as other core XML related classes.

  • System.Xml.Linq: Must add a reference to System .Xml.Linq assembly. Provides access to XDocument class for XML manipulation as well as LINQ language constructs.

  • System.Xml.Serialization: Provides access to XML serialization attributes that you can apply to .NET classes.

If you are a .NET developer, most of these look familiar, as they are the standard .NET classes related to serializing .NET objects, as well as reading and writing data to the file system. The one exception is possibly System.IO.IsolatedStorage, which is available via Silverlight on the desktop and also on Windows Phone 7. Isolated Storage represents the physical file system made available via the IsolatedStorage classes.

Unlike with Silverlight for the Web, there isn't an Isolated Storage quota on Windows Phone 7; however, it is recommended to not exceed two Gigabytes of data for an application if you are to be a good citizen and not abuse available space. Also, applications should make users aware of estimated file space requirements and try to give an option to delete data if needed. Keeping the user informed and in control is paramount.

The System.IO.IsolatedStorage namespace provides two possible methods to access the file system. The first is a key-value pair of type string-object where the key is a string and the value is of type object available in the static class IsolatedStorageSettings via its single property named ApplicationSettings. The Dictionary class stores object values, so essentially any class that can be serialized can be stored in the IsolatedStorageSettings.ApplicationSettings object. It is not limited to just simple values.

The other method to access the file system is via file and folder management using the IsolatedStorageFilestatic class. The method that provides access to the application's file system area is the GetUserStoreForApplication() method. With a reference to the user store in hand, you can create files to serialize objects to the file system.

The next two sections cover the sample code details for this section. The first example covers basic isolated storage operations, and the second example covers object persistence and serialization.

1. Basic File IO

Figure 1 has the UI.

Figure 1. DataPersistenceBasicIsoStorage UI

The UI has several controls that store fake settings and data values. The sample uses both the ApplicationSettings object and an IsolatedStorageFileStream object to store and retrieve the values.

NOTE

All of the data could persist within the ApplicationSettings object, but the sample shows how to work with the IsolatedStorageFileStream to prepare for more complex scenarios.

The code is straightforward Dictionary object access and file IO. See Listing 1.

Example 1. BasicIsoStorage.xaml.cs Code File
using System;
using System.IO;
using System.IO.IsolatedStorage;
using Microsoft.Phone.Controls;

namespace DataPersistence.pages
{
  public partial class BasicIsoStorage : PhoneApplicationPage
  {
    private const string fileName = "notes.dat";

    public BasicIsoStorage()
    {
      InitializeComponent();
    }

    private void saveAppBarIcon_Click(object sender, EventArgs e)
    {
      SaveData();
    }

    private void loadAppBarIcon_Click(object sender, EventArgs e)
    {
      LoadData();
    }

    private void LoadData()
    {
      //Load "settings"
      if (IsolatedStorageSettings.ApplicationSettings.Contains("EnablePush"))
        enableNotifications.IsChecked =
          (bool)IsolatedStorageSettings.ApplicationSettings["EnablePush"];
      if (IsolatedStorageSettings.ApplicationSettings.Contains("FavColor"))
        colorListBox.SelectedIndex =
          (int)IsolatedStorageSettings.ApplicationSettings["FavColor"];
      if (IsolatedStorageSettings.ApplicationSettings.Contains("NickName"))
        nicknameTextBox.Text =
          (string)IsolatedStorageSettings.ApplicationSettings["NickName"];

					  

//Load "notes" text to file
      using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
      {
        if (isf.FileExists(fileName))
        {
          using (IsolatedStorageFileStream fs =
            isf.OpenFile(fileName, System.IO.FileMode.Open))
          {
            using (StreamReader reader = new StreamReader(fs))
            {
              notesTextBox.Text = reader.ReadToEnd();
              reader.Close();
            }
          }
        }
      }

    }

    private void SaveData()
    {
      //Save "settings"
      IsolatedStorageSettings.ApplicationSettings["EnablePush"] =
        enableNotifications.IsChecked;
      IsolatedStorageSettings.ApplicationSettings["FavColor"] =
        colorListBox.SelectedIndex;
      IsolatedStorageSettings.ApplicationSettings["NickName"] =
        nicknameTextBox.Text;

      //Save "notes" text to file
      using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
      {
        using (IsolatedStorageFileStream fs =
          isf.OpenFile(fileName, System.IO.FileMode.Create))
        {
          using (StreamWriter writer = new StreamWriter(fs))
          {
            writer.Write(notesTextBox.Text);
            writer.Flush();
            writer.Close();
          }
        }
      }
    }
  }
}

					  

There are two application bar icons to load and save data. Loading data is a matter of checking that a key exists using ApplicationSettings.Contains, and then accessing the value via the key. The ApplicationSettings class is of type Dictionary that takes a key value of type String and stores the passed-in class as a type of Object. This permits you to pass any class into a Dictionary object, since all classes inherit from type Object. You must, however, type convert the retrieved object to the original type.Otherwise a runtime error will occur.

Loading the "Notes" TextBox data checks that the file exists and just reads the data using a StreamReader object. You may be tempted to put the filename into the StreamReader constructor directly. This will result in a code security access violation if you do. The only valid constructor parameter for an instance of StreamReader or StreamWriter is an object of type IsolatedStorageFile.

Saving the data is very similar code to loading the data. Note the use of the using construct for all objects that have a Dispose method. The following is the pseudocode:

Using (TextReader textReader = new StreamReader(streamResourceInfo.Stream)  // create
isntance { //...code that leverages the instance.... }//Disposed called automatically when the block is exited

NOTE

Only .NET objects that have handles to non-managed objects like a physical file handle have Dispose methods in .NET.

The using clause ensures that Dispose is called and that unmanaged resources are released. Otherwise, memory will not be freed immediately, and the runtime memory load will slowly increase until either Garbage Collection occurs or until the memory threshold limit is exceeded, and the app fails or until the application exits. Now that we've covered the basic isolated storage operations, we move on next to object persistence.

2. Object Persistence

In the previous section, we demonstrated how to store and retrieve individual values. In this section, we add some realism by serializing objects instead of individual values. The ObjectSerialization.xaml sample starts with almost the same UI and values as the BasicIsoStorage sample, but this time the controls data bind to a sample class named AppClass, as shown in Listing 2.

Example 2. AppClass.cs Code File
using System.Xml.Serialization;

namespace DataPersistence
{
  [XmlRootAttribute("AppClass")]
  public class AppClass
  {
    public AppClass()
    {
      FavoriteColor = −1;
    }

    //Settings
    [XmlElement]
    public bool EnablePushNotifications { get; set; }

    [XmlElement]

public int FavoriteColor { get; set; }

    [XmlElement]
    public string NickName { get; set; }

    //Data
    [XmlElement]
    public string Notes { get; set; }
  }
}

The sample AppClass class that we serialize in this example includes attributes from the System.Xml.Serialization namespace to provide support for serializing the object to the file system. The MSDN documentation covers all of the possible XML serialization attribute values:

http://msdn.microsoft.com/en-us/library/83y7df3e(v=VS.100).aspx

Configuring the data binding with Blend using sample data based on the AppClass is straightforward. A sample data source is added to the project that is based on the .NET AppClass class. This facilitates design-time data binding without causing issues at run-time.

In order to save and load the data, the code-behind for ObjectSerialization.xaml has modified Save and Load methods that serialize and deserialize an instance of the AppClass object, and configures it as the DataContext for the LayoutRoot Grid object. The following are the modified methods:

private void LoadData()
{
  using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
  {
    if (isf.FileExists(fileName))
    {
      using (IsolatedStorageFileStream fs =
        isf.OpenFile(fileName, System.IO.FileMode.Open))
      {
        XmlSerializer serializer = new XmlSerializer(typeof(AppClass));
        LayoutRoot.DataContext = (AppClass)serializer.Deserialize(fs);
      }
    }
  }
}

private void SaveData()
{
  using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
  {
    using (IsolatedStorageFileStream fs =
      isf.OpenFile(fileName, System.IO.FileMode.Create))
    {
      XmlSerializer xs = new XmlSerializer(typeof(AppClass));
      xs.Serialize(fs, ((AppClass)LayoutRoot.DataContext));
    }
  }
}

					  

The serialization attributes attached to the AppClass object tell the XmlSerializer object how to read and write the class in Xml format. From there, the rest of the code in SaveData and LoadData methods is boilerplated, isolated storage file I/O, as in the previous sample.

The samples in this section exposed data management issues when you run the sample application to test the samples. If you navigate away from the sample, such as going to the Start screen, and then navigate back, the UI resets to what it is at startup. The data that was displayed is not preserved. Serializing out UI objects and settings is a critically important requirement for Windows Phone 7 applications. The concepts covered in this section lay the groundwork for the section titled Application Life Cycle Management.

In that section, application and data architecture is discussed, such that the data can be made to appear to be preserved, and to the user it will appear that the application was waiting in the background for the user to return to it. Before jumping there, we cover launchers and choosers first in the next section.

Other -----------------
- Windows Phone 7 Programming Model : Device Information
- iphone Programming : Mixing OpenGL ES and UIKit, Rendering Confetti, Fireworks, and More: Point Sprites
- iphone Programming : Animation with Sprite Sheets, Image Composition and a Taste of Multitexturing
- XNA Game Studio 3.0 : Creating Game Components - Adding Game Sounds
- Iphone Application : Using Gesture Recognizers (part 4)
- Iphone Application : Using Gesture Recognizers (part 3)
- Iphone Application : Using Gesture Recognizers (part 2)
- Iphone Application : Using Gesture Recognizers (part 1)
- Handling Input on Windows Phone 7 : Microphone Input
- Handling Input on Windows Phone 7 : Accelerometer
 
 
REVIEW
- First look: Apple Watch

- 10 Amazing Tools You Should Be Using with Dropbox
 
VIDEO TUTORIAL
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
 
Popular tags
Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8 BlackBerry Android Ipad Iphone iOS
Popular keywords
HOW TO Swimlane in Visio Visio sort key Pen and Touch Creating groups in Windows Server Raid in Windows Server Exchange 2010 maintenance Exchange server mail enabled groups Debugging Tools Collaborating
Top 10
- Microsoft Excel : How to Use the VLookUp Function
- Fix and Tweak Graphics and Video (part 3) : How to Fix : My Screen Is Sluggish - Adjust Hardware Acceleration
- Fix and Tweak Graphics and Video (part 2) : How to Fix : Text on My Screen Is Too Small
- Fix and Tweak Graphics and Video (part 1) : How to Fix : Adjust the Resolution
- Windows Phone 8 Apps : Camera (part 4) - Adjusting Video Settings, Using the Video Light
- Windows Phone 8 Apps : Camera (part 3) - Using the Front Camera, Activating Video Mode
- Windows Phone 8 Apps : Camera (part 2) - Controlling the Camera’s Flash, Changing the Camera’s Behavior with Lenses
- Windows Phone 8 Apps : Camera (part 1) - Adjusting Photo Settings
- MDT's Client Wizard : Package Properties
- MDT's Client Wizard : Driver Properties
 
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
2015 Camaro