在DataContracts上使用INotifyChanged

时间:2010-01-25 15:08:32

标签: c# wcf events notifications inotifypropertychanged

我正在尝试将实际服务数据与服务功能分开,因此将数据作为包含多个属性(数据成员)的数据协定返回。使用svcutil / edb生成客户端代码,该代码还为代理代码生成INotifyPropertyChanged实现。就我的测试显示,该代码不会为服务器上发生的更改调用PropertyChanged事件。此外,获取属性只会返回获取数据合同代理时的属性值。

基本上,这就是我所拥有的:

(服务器端)

[ServiceContract]
public interface IControllerService
{
    [OperationContract]
    DataModel GetDataModel();
}

[DataContract]
public class DataModel : INotifyPropertyChanged
{
    private string _state;

    [DataMember]
    public string State
    {
        set
        {
            if (_state != value)
            {
                _state = value;
                OnPropertyChanged("State");
            }
        }
        get
        {
            return _state;
        }
    }

    public event PropertyChangedEventHandler  PropertyChanged;

    [OperationContract]
    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

(客户端)

private void Test()
{
    ControllerServiceClient client = new ControllerServiceClient();

    DataModel model = client.GetDataModel();
    model.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(DataModelChanged);

    Console.WriteLine(model.State);

    // ... invoke something that forces the server to change the data model

    // Output stays the same
    Console.WriteLine(model.State); 
}

private void DataModelChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
    // This method never get called for server-side changes
}

我希望数据合同代理充当服务器数据合同的透明代理,但它似乎完全没有绑定。

事先非常感谢, 欢呼声,

Romout

2 个答案:

答案 0 :(得分:2)

WCF不会神奇地为服务器端对象生成连接。它只是调用ServiceContract中定义的任何方法并将数据返回给您。除此之外没有其他沟通渠道。

因此,在您的方案中,您需要一个双工服务(请参阅:http://msdn.microsoft.com/en-us/library/cc645027%28VS.95%29.aspx),该服务会通过手动更改服务器来回调客户端。

答案 1 :(得分:1)

不要将DataContract视为“透明代理”,它更像是接口

仅仅因为两个类实现相同的接口,并不意味着它们完全相同。对于DataContract的客户端和服务器端也是如此。

客户端(这里)是基于DC生成的,还包括DataBinding有用的方面,比如INPC和ObservableCollections,就是这样,没有魔力。例如,如果服务器端对象上存在某些计算属性,则该逻辑将不会出现在客户端上。

正如已经提到的,如果您需要服务器在客户端上调用事件,您将需要某种双向绑定/服务,没有其他方法(除了通过轮询服务器来模拟它)等等。)