ObservableCollection和CollectionChanged事件作为WCF datacontract

时间:2011-12-23 05:41:38

标签: c# .net wcf observablecollection inotifycollectionchanged

我将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 个答案:

答案 0 :(得分:2)

这是因为您在序列化List时没有序列化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");
}

在这种情况下,事件将会触发。