2011-12-23 74 views
2

我用DataContract與的ObservableCollection:的ObservableCollection和CollectionChanged事件作爲WCF datacontract

[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

WCF數據合約應該**不包含任何邏輯/代碼,因爲該代碼**不能在服務器到客戶端之間的通信鏈路上串行化並返回。 WCF是一個**消息傳遞**系統 - 從客戶端到服務器的所有內容都是**串行化的XML消息**,並且這些消息不能包含行爲/邏輯/代碼。 – 2011-12-23 05:55:01

+0

好的,在這種情況下可以做什麼嗎?在客戶端集合發生更改時,我需要將我的合同標記爲(例如,將boolean datamember字段設置爲true)。隱含地在代碼中設置此字段是不可能的... – 2011-12-23 05:59:14

+0

客戶端上的這些數據契約將是* partial *類 - 您可以擴展它們以處理數據契約內的變更檢測和屬性設置。你只需要在客戶端使用該標誌嗎?或者你需要在某個時間點將它傳回服務器? – 2011-12-23 06:28:01

回答

2

這是因爲您在序列化list時未序列化List。因此,在反序列化期間它不會調用列表的setter,因此不會訂閱事件。你的情況,你可以簡單地標記ListDataMemberAttribute代替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"); 
} 

在這種情況下,事件將觸發。

相關問題