views:

282

answers:

1

I'm writing a plug-in for an application where I have a custom class that attributes the native objects of the program. The API allows me to read and write keyed strings directly to and from the objects in the native file. So rather then reading and writing to private fields in the Get and Set accessors of each property I'm reading and writing these user strings to and from the native objects in the program.

The user accesses these properties through a PropertyGrid control. So far this is all working fine with simple properties except now I need to store a custom collection (FloorCollection) of a custom object type (Floor).

So I've setup a property using XmlSerializer. The GET accessor reads the user string from the native objects, and then the string is deserialized into an instance of FloorCollection. The SET accessor does the reverse by reading in an instance of a FloorCollection, and serializing it to the user string.

Here's what my property looks like:

public FloorCollection Floors
{
    get 
    {
        string oldString = this.GetBaseObjUserString("CPFloors");
        if (oldString == null) return null;

        XmlSerializer serializer = new XmlSerializer(typeof(FloorCollection));
        StringReader strReader = new StringReader(oldString);

        FloorCollection newCollection =                 
        (FloorCollection)serializer.Deserialize(strReader);
        return newCollection;
    }

    set 
    {
        FloorCollection newCol = value;

        if (newCol == null) return;

        //serializes new collection
        XmlSerializer serializer = new XmlSerializer(typeof(FloorCollection));
        StringWriter sw = new StringWriter();

        serializer.Serialize(sw, newCol);

        string newString = sw.ToString();

        this.SetBaseObjUserString("CPFloors", newString);
    }
}

I can open this collection property through my PropertGrid in the default collection editor. However, the default collection editor only edits the collection at the reference provided by the GET accessor, rather then calling the SET accessor to save it back to the object. So I can edit the collection in the default editor, but when I close and reopen the editor the collection will not have changed because the SET accessor is never called to serialize the collection back to the user string in the native object.

Can I modify the default collection editor to call the set accessor of the property? If I setup a custom UITypeEditor for the property is there a way to have it save back to the property using the property set accessor? Or is there some other way to force code that is accessing the collection property to GET and SET the property by value rather then reference?

A: 

I don't believe the XML Serializer will ever call the set accessor for a collection. Instead, it will just call the Add method of the collection instance it retrieves from the get accessor.

I believe you'll need to have your collection type override the Add and Remove methods and such to modify the collection, and then serialize the modified collection back into the user property.

John Saunders
Hu? You got it backwards. The set accessor is where the serialization happens, just as the get accessor is where the deserialization happens. The problem is when I edit the the collection through a PropertyGrid with the default collection editor or a custom UITypeEditor the reference collection is edited directly rather then being passed back through my SET acessor where it would serialize the new value.
Eric Anastas
No, I've got it real. Because the set accessor will never be called, you're going to need a special collection which will serialize whenever the collection is changed.
John Saunders
Well the collection really doesn't need to know to serialized when it is changed. Rather the class with the collection needs to know when the the collection changes so it can re-serialize it. My custom collection inherit from BindingList<Floor> so it does have a listchanged event that I could subscribe to.
Eric Anastas