Subscribing to PropertyChanged from WCF DataContract proxy classe

I like the idea of โ€‹โ€‹extending to client classes, which are WCF service data contracts using partial classes. But I ran into a problem that significantly spoils the side.

Imagine that on the server side I have a class:

[DataContract] public class SolidObject { [DataMember] public Point Position { get; set; } [DataMember] public Size Size { get; set; } } 

On the client side, I have created a proxy class that is used there at the level of business logic. In accordance with the needs of business logic, I expand it as follows:

 public partial class SolidObject { public Rect Bounds { get { return new Rect(Position.X - Size.Width / 2, Position.Y - Size.Height / 2, Size.Width, Size.Height); }} } 

Now I want the position or size to change at any time, then the Chounds chage event is fired. The code is easy to execute:

 PropertyChanged += (sender, e) => { if ((e.PropertyName == "Position") || (e.PropertyName == "Size")) PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Bounds")); }; 

The question is where is a good place to enter this code.

If the objects were not created by a service call, I would put it in the constructor. But WCF services ignore client-side constructors, see a constructor that does not appear in my WCF client, serialization problem? .

Now, right after the response of the service, my program searches the hierarchy of data contracts, receives the desired objects and adds event handlers. But I do not think this is right.

So, I wonder where this is best done, or maybe reasoning that the whole approach needs to be changed. Any ideas appreciated.

+4
source share
3 answers

You can use the [OnDeserlialized] attribute to insert a method that is called after deserialization.

 public partial class SolidObject { public Rect Bounds { get { return new Rect(Position.X - Size.Width / 2, Position.Y - Size.Height / 2, Size.Width, Size.Height); } } [OnDeserialized] public void Initialize(StreamingContext streamingContext) { PropertyChanged += (sender, e) => { if ((e.PropertyName == "Position") || (e.PropertyName == "Size")) PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Bounds")); }; } } 
+4
source

I would recommend using a view model rather than a partial class.

 public class SolidObjectViewModel : INotifyPropertyChanged { private SolidObject _solidObject; public SolidObjectViewModel(SolidObject solidObject) { _solidObject = solidObject; _solidObject.PropertyChanged += (sender, e) => { bool positionChanged = e.PropertyName == "Position"; bool sizeChanged = e.PropertyName == "Size"; if (positionChanged) FirePropertyChanged("Position"); if (sizeChanged) FirePropertyChanged("Size"); if (positionChanged || sizeChanged) FirePropertyChanged("Bounds"); }; } public Point Position { get { return _solidObject.Position; } set { _solidObject.Position = value; } } public Size Size { get { return _solidObject.Size; } set { _solidObject.Size = value; } } public Rect Bounds { get { return new Rect(Position.X - Size.Width / 2, Position.Y - Size.Height / 2, Size.Width, Size.Height); } } public event PropertyChangedEventHandler PropertyChanged; private void FirePropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } 
+2
source

I would say do not use the generated class if there is business logic to be implemented. Save your model by running a client-side implementation of SolidObject. When you create proxies, you can use the reuse class option from this DLL.

It does not make sense for the entity to join its own event. Implementation would be.

 [DataContract] public class SolidObject { [DataMember] public Point Position { get { return _position; } set { position = value; FirePropertyChanged("Position"); FirePropertyChanged("Bounds"); } } public Size Size { //similar to position } public Rect Bounds { get { return new Rect(Position.X - Size.Width / 2, Position.Y - Size.Height / 2, Size.Width, Size.Height); }} } 
0
source

Source: https://habr.com/ru/post/1299962/


All Articles