2

I use DataContract with 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?"); 
                    };
            }
        }
...

So, when I work with my collection like this.

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

Item was been added but CollectionChanged event not fired.

Why?

Kirill Polishchuk
  • 54,804
  • 11
  • 122
  • 125
weqew q
  • 271
  • 3
  • 10
  • 1
    WCF data contract ought **not** to contain any logic / code since that code **cannot** be serialized across the communications link from server to client and back. WCF is a **message-passing** system - all that goes from client to server and back are **serialized XML messages** and those cannot contain behavior/logic/code. – marc_s Dec 23 '11 at 05:55
  • Ok, is it poosible anything to do in this situation? I need mark my contract(for example set additionally boolean datamember field to true) when in client collection was changed. Set this field implicitly in code isn't possible... – weqew q Dec 23 '11 at 05:59
  • Those data contracts on the client-side will be *partial* classes - you can extend those to handle the detection of change, and setting of a property inside the data contract. Do you need that flag only on the client?? Or do you need to transfer that back to the server at some point?? – marc_s Dec 23 '11 at 06:28
  • I need to transer this flag back to the server. And the problem is when I extend my contract it doesent work fot Observable colletion. So if I set my flag in set section of property - it works fine, but if I work with obserablese collection throw Add, Insert and Remove methods I couldn't detect that collection was changed. Because OnCollectionChanged event doesn't work. – weqew q Dec 23 '11 at 06:36

1 Answers1

3

That is because you don't serialize List while serialize list. So, during deserialization it won't call setter of list, therefore won't subscribe to event. In your case you can simply mark List with DataMemberAttribute instead of list, e.g.:

[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?!");
        }
    }
}

Usage:

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");
}

In this case event will fire.

Kirill Polishchuk
  • 54,804
  • 11
  • 122
  • 125