Windows Phone 7 XML IsolatedStorage Example

For one of the apps I have been working on, I needed to persist a List<T> of T objects across sessions. They are simple objects with simple properties, so I decided to use XML. However, since WP7 is a new platform, there’s not a lot of information out there on what is a good best practice.

It turns out for simple situations like mine, serializing objects into XML and writing that to file is by far the easiest way to do it.

Let’s examine a scenario.

The App

This is not an app I am working on, but it is basically the same thing.

Let’s say that you want to track your jogs. Starting simple, you decide to track the following properties:

  • RouteID : int
  • Duration : TimeSpan (we will encounter an interesting serialization bug with TimeSpan as well)
  • Date : DateTime
  • Distance (miles) : float

Of course, we won’t attempt to build all of this here, but rather, focus on the storage aspect of it.

The “Jog” Object

You will persist a list of these objects to be able to view them historically. This is what a Jog object might look like. Note the extra property, DurationXml, with its special attributes – this exists because XmlSerializer does not properly serialize TimeSpan objects.

 

代码
public   class  Jog
    {
        
private  TimeSpan _duration  =   new  TimeSpan();
        
public  DateTime Date {  get set ; }
        [XmlIgnore]
        
public  TimeSpan Duration
        {
            
get  {  return  _duration; }
            
set  { _duration  =  value; }
        }
        
//  HACK: This property only exists for XML serialization.
        
//  It gets serialized as a <Duration> tag.
        [XmlElement( " Duration " , DataType = " duration " )]
        
public   string  DurationXml
        {
            
get
            {
                
return  XmlConvert.ToString(_duration);
            }
            
set
            {
                
if  (value  ==   null )
                {
                    _duration 
=  TimeSpan.Zero;
                    
return ;
                }
                TimeSpan newDuration 
=  XmlConvert.ToTimeSpan(value);
                
if  (_duration  ==  newDuration)
                    
return ;
                _duration 
=  newDuration;
            }
        }
        
public   int  RouteID {  get set ; }
        
public   float  Distance {  get set ; }
    }

 

 

 

Note the hackery around the Duration and DurationXml properties.

Jog List

For the purposes of this app, you’d have a List of Jog objects: List<Jog> which you keep as a static on the App class and maintain it there. You’d then create some methods in the App class that would help out with storage, and then call them from Application_Closing, Application_Launching, and Activated/Deactivated as you handle tombstoning and deactivation.

Storage Helper

Then, you might write a class like this which helps with storage, and keep it statically on the App class. All you have to do is call XmlSerializer.Serialize(object) and XmlHelper.Deserialize(xml) to manage the saving/loading of your object list. Put together, it looks like this:

 

代码
  public   class  StorageHelper
    {
        
private   const   string  FILE_NAME  =   " Jogs.xml " ;
        
public  List < Jog >  LoadJogs()
        {
            List
< Jog >  jogs  =   new  List < Jog > ();
            TextReader reader 
=   null ;
            
try
            {
                IsolatedStorageFile isoStorage 
=  IsolatedStorageFile.GetUserStoreForApplication();
                IsolatedStorageFileStream file 
=  isoStorage.OpenFile(FILE_NAME, FileMode.OpenOrCreate);
                reader 
=   new  StreamReader(file);
                 XmlSerializer xs 
=   new  XmlSerializer( typeof (List < Jog > ));
                feedings.AddRange((List
< Jog > )xs.Deserialize(reader));
                reader.Close();                
            }
            
catch
            {
                
            }
            
finally
            {
                
if  (reader  !=   null )
                    reader.Dispose();                
            }
            
return  jogs;
        }
        
public   void  SaveJogs(List < Jog >  jogs)
        {
            TextWriter writer 
=   null ;
            
try
            {
                IsolatedStorageFile isoStorage 
=  IsolatedStorageFile.GetUserStoreForApplication();
                IsolatedStorageFileStream file 
=  isoStorage.OpenFile(FILE_NAME, FileMode.Create);
                writer 
=   new  StreamWriter(file);
                XmlSerializer xs 
=   new  XmlSerializer( typeof (List < Jog > ));
                xs.Serialize(writer, jogs);
                writer.Close();
            }
            
catch
            {
            }
            
finally
            {
                
if  (writer  !=   null )
                    writer.Dispose();
            }
        }
        
public  StorageHelper()
        {
        }
    }

 

 

 

Don’t Forget Your References

One thing to note here is that several of the Xml classes won’t magically work with IntelliSense. You need to add references to System.Xml and System.Xml.Serialization for all this good stuff to work.

I’ll be posting an example Jog Tracker application that uses isolated storage in the coming weeks, but for now, this should be enough to get you started.

 

你可能感兴趣的:(windows phone)