ObservableCollection и CollectionChanged событие как WCF datacontract


Я использую DataContract с ObservableCollection:

[DataContract(Namespace = Terms.MyNamespace)]
public class MyContract 
{
internal MyContract ()
        {
            List = new ObservableCollection<string>();
        }
[DataMember]
private ObservableCollection<string> list;

[XmlArray("list")]
        public ObservableCollection<string> List
        {
            get
            {
                return list;
            }
            set
            {
                list = value;
                list.CollectionChanged += (s, e) =>
                    { 
                        Console.WriteLine("It is never happens!! Why?"); 
                    };
            }
        }
...

Итак, когда я работаю со своей коллекцией вот так.

MyContract contract = new MyContract();
contract.List.Add("some");

Элемент был добавлен, но событие CollectionChanged не было запущено.

Почему?

1 2

1 ответ:

Это потому, что вы не сериализуете List, а сериализуете list. Так, во время десериализации он не вызовет setter списка, поэтому не подпишется на событие. В вашем случае вы можете просто отметить List с DataMemberAttribute вместо list, например:

[DataContract]
public class MyContract
{
    private ObservableCollection<string> list;

    internal MyContract()
    {
        List = new ObservableCollection<string>();
    }

    [DataMember]
    public ObservableCollection<string> List
    {
        get
        {
            return list;
        }
        private set
        {
            list = value;
            list.CollectionChanged += 
               (s, e) => 
                   Console.WriteLine("It is never happens!! Why? - Are you sure?!");
        }
    }
}

Использование:

var obj = new MyContract();

var serializer = new DataContractSerializer(typeof(MyContract));

using (var ms = new MemoryStream())
{
    serializer.WriteObject(ms, obj);

    ms.Seek(0, SeekOrigin.Begin);

    var result = serializer.ReadObject(ms) as MyContract;

    result.List.Add("a");
}

В этом случае событие выстрелит.