views:

167

answers:

2

I've got a settings object for my app that has two collections in it. The collections are simple List generics that contain a collection of property bags. When I serialize it, everything is saved with no problem:

XmlSerializer x = new XmlSerializer(settings.GetType());
TextWriter tw = new StreamWriter(@"c:\temp\settings.cpt");
x.Serialize(tw, settings);

However when I deserialize it, everything is restored except for the two collections (verified by setting a breakpoint on the setters:

XmlSerializer x = new XmlSerializer(typeof(CourseSettings));
XmlReader tr = XmlReader.Create(@"c:\temp\settings.cpt");
this.DataContext = (CourseSettings)x.Deserialize(tr);

What would cause this? Everything is pretty vanilla... here's a snippet from the settings object... omitting most of it. The PresentationSourceDirectory works just fine, but the PresentationModules' setter isn't hit:

private string _presentationSourceDirectory = string.Empty;
public string PresentationSourceDirectory {
  get { return _presentationSourceDirectory; }
  set {
    if (_presentationSourceDirectory != value) {
      OnPropertyChanged("PresentationSourceDirectory");
      _presentationSourceDirectory = value;
    }
  }
}

private List<Module> _presentationModules = new List<Module>();
public List<Module> PresentationModules {
  get {
    var sortedModules = from m in _presentationModules
                        orderby m.ModuleOrder
                        select m;
    return sortedModules.ToList<Module>();
  }
  set {
    if (_presentationModules != value) {
      _presentationModules = value;
      OnPropertyChanged("PresentationModules");
    }
  }
}
A: 

You can override the serialization and de-serialization methods to add custom information. It's been awhile since I implemented something like this, but I recall having to override to reconstruct some private members from the object upon receiving the serialization data.

gsiener
+1  A: 

If a list is deserialized, the setter is never called. Just the getter. The Deserializer just invokes the #Add() method and adds the serialized elements to the exising List. This is behaviour by Design. See MSDN.
You could add a new property wich gets your list without any linq statements. Add an [XmlIgnore] to your existing property, the XmlSerializer will skip this property now.

[XmlIgnore]
public List<Module> PresentationModules {

Create a new property which exposes the list:

private List<Module> _presentationModules = new List<Module>();
public List<Module> PresentationModulesList {
  get { return _presentationModules; }
}

Your event in the setter of PresentationModules will only be invoked if you assign a NEW list to the property. Maybe you should make the setter private.

chriszero
OK, this makes sense, but I'm not clear on what my option is to get this resolved. It appears I have to go back and implement a custom serializer/de after modifying my object so it doens't accept a setter for the collection... is that the only option?
AC
I have updated my answer. maybe this is what you are want. Is the event which you are invoking in the setter a requirement?
chriszero
Thanks chriszero... got some work to do now... many thanks!
AC