Setters for Dependents

May 29, 2013 at 8:50 AM
Edited May 29, 2013 at 8:53 AM
I have an issue with the Silverlight 4 and 5 versions of Update Controls that does not present in the WPF version.

Following your ledger example in ProvableCode (great PluralSight course btw), I built my Transaction to have just an "Amount" property, and coded the Increase/Decrease in the TranscationViewModel like this:
    public decimal Increase
    {
        get
        {
            return _transaction.Amount > 0
                ? _transaction.Amount
                : 0m;
        }
        set { _transaction.Amount = value; }
    }

   public decimal Decrease
   {
        get
        {
            return _transaction.Amount < 0
                ? -_transaction.Amount
                : 0m;
        }
        set { _transaction.Amount = -value; }
    }
This is intended to support a scenario like this: I enter -40 into Decrease property, and the Increase property is set to 40 and the Decrease property coerced to 0.

This works in WPF just fine, however, in Silverlight if the negative value entered is such that the underlying Amount doesn't change, then the edited property is not coerced. E.g. Increase is 40, Decrease is 0. I set Decrease to -40 and it stays as -40 - it's not coerced back to 0.

Any ideas how to fix this? Obviously the issue is related to the fact that Amount does not change - but you've managed to address this in WPF, just wondering if we can port the magic to Silverlight. :)

I'm also wondering if this is even a "correct" thing to do. If it isn't correct, I'm not sure how to handle it as the user requirement doesn't seem unreasonable.


Thanks.
Coordinator
May 29, 2013 at 4:34 PM
What you are running in to is a known bug in the Silverlight data binding debugger. Please try running your application outside of the debugger by using Ctrl+F5 and see if it works. It made a difference in my repro.

Please see the accepted answer here:

http://social.msdn.microsoft.com/Forums/en-US/silverlightstart/thread/2051647a-25ac-4f65-acf0-d06da4a1d26f/

More information at these links:

http://stackoverflow.com/questions/11965408/coerce-value-in-property-setter-silverlight-5
http://social.msdn.microsoft.com/forums/en-US/wpf/thread/6f78d75f-9769-4ff9-a76f-c2af0040d9b0

Thanks!
May 29, 2013 at 8:31 PM
Hi Michael,

I'm actually aware of that bug - apologies, I should have mentioned I have tried disabling binding debugger and also running without the debugger attached - the problem is still there. (Also tried running Release build without debugging.)

I've uploaded my sample projects so you can see for yourself - there's a working WPF project and a Silverlight 5 example exhibiting the problem (although it occurs in SL4 too).

You can download it here: http://sdrv.ms/ZtKz63 (it's VS2012).

To see the problem enter -30 in the top "Decrease" box - nothing will update.
Now restart and enter -30 into the "Increase" box and the Increase box will correctly go to zero and the Decrease box to 30.

The behaviour isn't very predictable - playing around entering negative values in different boxes gives inconsistent results. This is seems to be something else than the binding debugger issue.

Cheers,

James.
Coordinator
May 29, 2013 at 11:33 PM
Thank you for the project. This made it really easy to find the problem. I'll have a fix published very soon.

The problem occurs when you change from a zero to a negative number for the second time. It sees that the value was zero the last time it updated, and that it is trying to update to a zero again. So it doesn't fire property changed.

I am taking out that check and firing property changed every time. The minor optimization is not worth trying to figure out when it's superfluous.
May 30, 2013 at 12:06 AM
Thanks - I'm looking forward to it! This project could really help clean up some code of mine.
Coordinator
May 30, 2013 at 12:44 PM
The fix is posted on NuGet and as an MSI download.

Thank you so much for finding this bug!
May 30, 2013 at 9:13 PM
Thanks for turning it round so fast! I've tested the fix too and it looks good.