RajenK
RajenK

Reputation: 1423

IsolatedStorageSettings.ApplicationSettings not persisting all properties

I'm trying to serialize and deserialize this class to Windows Phone ApplicationSettings, but for some reason, only the Items are persisted and not the Title or LastChanged properties. Any ideas as to why are appreciated!

Class:

public class VehicleCollection : ObservableCollection<Vehicle>
{
    public string Title { get; set; }
    public DateTime LastChanged { get; set; }

    public bool HasNoItems { get { return Items.Count == 0; } }

    public VehicleCollection() { }
    public VehicleCollection(string title, DateTime lastChanged)
    {
        Title = title;
        LastChanged = lastChanged;
    }

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        base.OnCollectionChanged(e);
        OnPropertyChanged(new PropertyChangedEventArgs("HasNoItems"));
    }
}

Persist logic:

    public static bool SavePersistent(string key, object value)
    {
        if (null == value)
            return false;

        var store = IsolatedStorageSettings.ApplicationSettings;
        if (store.Contains(key))
            store[key] = value;
        else
            store.Add(key, value);

        store.Save();
        return true;
    }

    public static T LoadPersistent<T>(string key)
    {
        var store = IsolatedStorageSettings.ApplicationSettings;
        if (!store.Contains(key))
            return default(T);

        return (T)store[key];
    }


Edit: I've created a sample project where the behavior is evident. http://www.fileswap.com/dl/2ar0ygF8w7/

  1. Run the app and watch the static data being created
  2. Press "save data" to save to IsolatedStorage
  3. Close and re-run the app
  4. Watch the title for both collections disappear, as they were not persisted

Upvotes: 3

Views: 712

Answers (2)

LocalJoost
LocalJoost

Reputation: 425

My best guess is the problem arises from the fact that you inherit your VehicleCollection class from ObservableCollection and that serialization and deserialization have a piece of code in them like 'if object is ObservableCollection'. I've tried your sample solution and the getter of the members is simply not called on serialization, nor is the setter called on deserialization.

The solution would be to refactor your VehicleCollection class like this:

  public class VehicleCollection 
  {
      public string Title { get; set; }
      public DateTime LastChanged { get; set; }

      public bool HasNoItems { get { return Items.Count == 0; } }

      public VehicleCollection() 
      { 
        Items = new ObservableCollection<Vehicle>()
      }
      public VehicleCollection(string title, DateTime lastChanged) :this()
      {
          Title = title;
          LastChanged = lastChanged;
      }

      public ObservableCollection<Vehicle> Items

  }

The bad thing of course is that then VehicleCollection needs to implement INotitifyPropertyChanged to get the HasNoItems to fire. Anyway - if I change it this way in your sample solution it works.

Upvotes: 1

Matt
Matt

Reputation: 1582

[This is not directly an answer to your question, but is a solution.]

Chances are you are already using JSON.NET or something similar. What about using that to serialize the object into a string, then save the string?

Using JSON.NET, this would change your code to:

        public static bool SavePersistent(string key, object value)
    {
        if (null == value)
            return false;

        value = JsonConvert.SerializeObject(value);
        var store = IsolatedStorageSettings.ApplicationSettings;
        if (store.Contains(key))
            store[key] = value;
        else
            store.Add(key, value);

        store.Save();
        return true;
    }

    public static T LoadPersistent<T>(string key)
    {
        var store = IsolatedStorageSettings.ApplicationSettings;
        if (!store.Contains(key))
            return default(T);

        return JsonConvert.DeserializeObject<T>((string)store[key]);
    }

And it will probably give you better performance anyway.

Upvotes: 0

Related Questions