1

Say I have a view model which has price and quantity properties in a view model implementing INotifyPropertyChanged which are bound to text boxes and total cost property which is bound to a text block. When either the price or the quantity is updated the total cost should be recalculated.

I understand that it desirable to minimize the amount of work that is done inside property setters and getters. Is it bad practice to trigger the calculation from setters of the properties? If it is bad practice how else should I do it? I can see two possibilities.

  1. Subscribe to the PropertyChanged event and trigger the calculation from there. I feel this event is more for outside observers than for use in the view model itself, and in any case any the event is triggered from the setter so I don't see how it is much different from triggering the processing from setter directly.

  2. Trigger the calculation from an event on the text box (say LostFocus) the property is bound to either by directly calling a method on the view model from the event or by binding the event to a command on the view model. It seems to me that with MVVM the idea is that we should avoid using control events if possible.

Shane
  • 2,271
  • 3
  • 27
  • 55

1 Answers1

0

I am afraid this could by a primarily opinion-based question, anyway I would like to share my idea.

I do not see too many problems in triggering the calculation in a property setter. Probably it is important how you do it. IHMO it is not good to replicate OnPropertyChanged("CalculatedPropertyName") everywhere around in your code.

I would prefer something like:

public int Quantity
{
    get { return quantity; }
    set 
    {
        if (value != quantity)
        {
            quantity = value;
            OnPropertyChanged();
            Result = Quantity * Price;
        }
    }
}

public int Price
{
    get { return price; }
    set 
    {
        if (value != price)
        {
            price = value;
            OnPropertyChanged();
            Result = Quanity * Price;
        }
    }
}

public int Result
{
    get { return result; }
    private set 
    {
        if (value != result)
        {
            result = value;
            OnPropertyChanged();
        }
    }
}

In this way you are just using a private setter and you do not need to remember to raise anything. This is the way I prefer, but if you are looking for more complex ways you can find a lot of ideas here and here.

Last thing - but not least - I do not like alternative ways you suggested, I feel they are too twisted.

Il Vic
  • 5,576
  • 4
  • 26
  • 37