views:

854

answers:

3

I have a model that looks roughly like this:

private bool IsProduct {get; set;}
private decimal ProductPrice {get; set;}
private decimal TimedRate {get; set;}

    public decimal SingularAmount {
        get {
            if (this.IsProduct) {
                return ProductPrice;
            }
            else {
                return TimedRate;
            }
        }
        set {
            if (this.IsProduct) {
                this.ProductPrice = value;
            }
            else {
                this.TimedRate = value;
            }
        }
    }

I'm binding to this SingularAmount property via RIA Services to Silverlight 3 DataGrid. What I'm finding is that, when I change the property - the respective properties on the model do not get updated. When I step through the code, I can see on the client side, that SingularAmount is set to say 5 for example, the other properties do not get updated.

Seems like when RIA makes the client side version of the classes, this sort of functionality isn't ported over. Any ideas on how to tackle this?


Update

Here is the RIA generated code for that property:

    [DataMember()]
    public decimal SingularAmount
    {
        get
        {
            return this._singularAmount;
        }
        set
        {
            if ((this._singularAmount != value))
            {
                this.ValidateProperty("SingularAmount", value);
                this.OnSingularAmountChanging(value);
                this.RaiseDataMemberChanging("SingularAmount");
                this._singularAmount = value;
                this.RaiseDataMemberChanged("SingularAmount");
                this.OnSingularAmountChanged();
            }
        }
    }

Obviously, that doesn't look much like the original server side property.

A: 

I'm just learning RIA Services myself, and am wondering if you can override the default constructor in this case? Although, I believe the recommended solution for this scenario is to have a Setter method (as in {obj}.SetPrice(decimal price); instead of doing what you are doing... Just my $0.02

Richard B
+1  A: 

When you're doing any data binding in Silverlight on to standard CLR properties (as opposed to Dependency Properties) then the binding object looks to see if the object implements INotifyPropertyChanged and listens for PropertyChanged events.

Implementing this on your model will cause the binding properties to update in the UI correctly.

There is one caveat though, due to the way your property SingularAmount is implemented (calculated from other values) you'll need to notify the UI about changes to that property as well.

So in the setter of ProductPrice you'll need to raise the PropertyChanged event for ProductPrice as well as Singular Amount.

This http://msdn.microsoft.com/en-us/library/cc278072(VS.95).aspx discusses data binding in Silverlight and how notifications work.

Nigel Sampson
Thanks, I tried your solution, however RIA Services sitting in the middle causes some headaches. Please see my updated question which shows the client side code generated by RIA services.
DaRKoN_
You should be able to inject the behavior you want through the use of partial classes and methods. The method "OnSingularAmountChanged" is a partial method which means you can implement it in a partial class and raise the PropertyChanged for other properties as well. Not ideal, it's why I don't like designer generated code.
Nigel Sampson
+1  A: 
Klinger
It seems the shared.cs only works for classes in the same project as RIA Services, which my model isn't.
DaRKoN_
.shared. only works if the file is within the RIA Services server side project.The reason why you cannot use it has to do with the fact that partial classes only work within the same assembly.Another way to extend your entity (client side only) is by addingthe partial class in the client side project.
Klinger
Got the shared code business working, however update on the domain context stops working if I alter this property.
DaRKoN_
I can confirm that the new and correct property values are being sent over the wire - it's just the update method in my RIA Service is never called if this property is touched. If I leave it alone (and change some other standard ones) update works fine.
DaRKoN_
Changing the private fields won't trigger the tracking mechanism. You have to change a real Property. A property that is part of your entity. The "set" part of a property will invoke RaiseDataMemberChanged("PropertyName") This will change the state of the entity as long as you have called BeginEdit in it (the entity I mean). Or you call it yourself on the set method. this.RaiseDataMemberChanged("SingularAmount"); That should do it.
Klinger