AllDayPiano
AllDayPiano

Reputation: 424

Deserialization of ObservableCollection kills events?

I have an ObservableCollection that is typeof UITestCaseElement:

public ObservableCollection<UITestCaseElement> TestCases = new ObservableCollection<UITestCaseElement>();

public class UITestCaseElement : IDisposable
{
    public int UniqueIdentifier { get; set; }
    public string TestCaseName { get; set; }
    public string TestCaseDescription { get; set; }

    public int RepeatCount { get; set; }

    [XmlIgnore] 
    public int NumOfRuntimes { get; set; }

    public bool IsActive { get; set; }

    [XmlIgnore]
    public Testcases.AbstractTestCase TestObject { get; set; }

    [XmlIgnore]
    public OMS4Driver.DeviceObject DeviceObject { get; set; }

    [XmlIgnore]
    public OMS4Driver.ClientObject ClientObject { get; set; }

    [XmlIgnore]
    public OMS4Driver.Generic.CameraSelect SelectedCamera { get; set; }

    public void Dispose() { }
}

And here's the way I open the generated XML:

private void mnuLoadConfig_Click(object sender, EventArgs e)
{
    var serializer = new XmlSerializer(typeof(System.Collections.ObjectModel.ObservableCollection<UITestCaseElement>));

    using (var reader = new StreamReader(@"C:\Users\xxx\Desktop\test.xml"))
    {
        _tcMngr.TestCases = (System.Collections.ObjectModel.ObservableCollection<UITestCaseElement>)serializer.Deserialize(reader);
    }

}

If the collection is beeing changed, it fires an event to the main form starting some handling on the UI.

Everything works fine (usage, export) but as soon as I de-serialize the xml file and copy back the ObservableCollection, the ObservableCollection events won't be fired anymore. If I debug the TestCases Instance, then all changes can be found within this collection.

Why?

Thank you very much!

Update:

I overwrite the complete collection and thus there's no delegate for the events pointing to my event handler anymore. That's stupid somehow. Thanks @all for you help.

Upvotes: 0

Views: 227

Answers (3)

Krazibit312
Krazibit312

Reputation: 390

You're replacing the collection here

 _tcMngr.TestCases = (System.Collections.ObjectModel.ObservableCollection<UITestCaseElement>)serializer.Deserialize(reader);

Trying clearing your current collection and add new items.

Upvotes: 1

Khanh TO
Khanh TO

Reputation: 48982

This is expected behavior, when you serialize your ObservableCollection, all the event handlers are not serialized. It's problematic if it's possible because these are addresses in memory. Everytime we run the application, these addresses are not the same.

That's why de-serializing does not get it back to the original state.

Upvotes: 1

Patrick Hofman
Patrick Hofman

Reputation: 157048

That is simply because you replace the entire collection. Those events are not registered on the new instance, created on calling Deserialize. (De)serialization does only serialize the data, not the events.

I would suggest to clear the current collection and add all items from the deserialized collection to it.

var newCollection = (ObservableCollection<UITestCaseElement>)serializer.Deserialize(reader);

_tcMngr.TestCases.Clear();

foreach (var item in newCollection)
{
    _tcMngr.TestCases.Add(item);
}

In this way, the original _tcMngr.TestCases stays intact, including all of its event handlers.

Upvotes: 2

Related Questions