views:

41

answers:

2

I'm using some CLR objects that use the INotifyPropertyChanged interface and use the PropertyChanged function to update in WPF bindings.

Pretty boilerplate:

protected void RaisePropertyChanged(string propertyName)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Then the property:

    private double m_TotalWidgets = 0;
    public double TotalWidgets
    {
        get { return m_TotalWidgets; }
        set 
        { 
            m_TotalWidgets = value;
            RaisePropertyChanged("TotalWidgets");
        }
    }

Is there a better way to update a derived value or even the whole class?

Say I had a calculated value:

    public double ScaledWidgets
    {
        get 
        { 
            return TotalWidgets * CONSTANT_FACTOR;
        }
    }

I would have to fire ScaledWidget's PropertyChanged when TotalWidgets is updated, eg:

        set 
        { 
            m_TotalWidgets = value;
            RaisePropertyChanged("TotalWidgets");
            RaisePropertyChanged("ScaledWidgets");
        }

Is there a better way to do this? Is it possible "invalidate" the whole object, especially if there are a lot of derived values? I think it would be kind of lame to fire 100 PropertyChanged events.

A: 

I don't know if there is a better way but I can suggest two things:

  1. Create a class that encapsulates the firing of the PropertyChanged event so you don't have to write a lot of boilerplate code. You just have to declare the PropertyChanged event and use that class to invoke it.
  2. If there are properties that are dependent from each other. Create a handler to the independent property so that every time it changes you can invoke the dependent properties. For example you can have an internal handler for TotalWidgets so that when it changes, you can change ScaledWidgets accordingly.

Why do you have to write 100 PropertyChanged events? Maybe it's not necessary and the problem is somewhere else.

John
1. Already done. Left it out of my example for brevity.2. I'm not sure I understand what you're saying here. ScaledWidgets' actual value is already updated, since the getter is just using TotalWidgets' property value to calculate it.What I'm saying is how do I notify any bindings that ScaledWidgets' value has changed BECAUSE TotalWidgets' value has changed. What if there were, say 20 scaled values, then I'd have to notify using:RaisePropertyChanged("ScaledWidgets1");RaisePropertyChanged("ScaledWidgets2");...RaisePropertyChanged("ScaledWidgets20");.. in the setter for TotalWidgets.
rrhartjr
+3  A: 

You can raise the PropertyChangedEvent with the parameter string.empty or null. Then all properties of the object get "invalidated". See my post here

Jehof
Perfect! Exactly what I needed to know!
rrhartjr