PropertyChanged

Developer
Feb 7, 2011 at 10:33 PM

Just downloaded the source code last week and am very impressed! I really appreciate the numerous samples as well as the effort that must have gone into making the code easily understandable. Great job.

I'm attempting to handle the PropertyChanged event for notification whenever a property value changes, and have noticed two things:

1) Multiple events are raised for the same property, and

2) The OldValue member of the PropertyChangedEventArgs is always null.

 

I made some very small changes to fix both of these problems and am curious what you think. Firstly, in PropertyEditor.cs:

 

private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    var property = sender as PropertyViewModel;
    if (property != null && e.PropertyName == "Value")
    {
        RaisePropertyChangedEvent(property.PropertyName, property.OldValue, property.Value);
        UpdateOptionalProperties(property);
    }
    if (e.PropertyName != "IsEnabled" && e.PropertyName != "IsVisible"
        && e.PropertyName != "PropertyError" && e.PropertyName != "PropertyWarning")
    {
        UpdatePropertyStates(SelectedObject);
        UpdateErrorInfo();
    }
}

 

RaisePropertyChangedEvent will no longer be called if e.PropertyName != Value. This eliminates the multiple events. I am also keeping track of the old value in the PropertyViewModel and am sending that along in the event. Here's the code for the OldValue, in PropertyViewModel.cs:

 

        public object Value
        {
            get
            {
                object value;
                if (IsEnumerable)
                {
                    var list = Instance as IEnumerable;
                    if (list == null)
                    {
                        throw new InvalidOperationException("Instance should be a list.");
                    }
                    value = GetValueFromEnumerable(list);
                }
                else
                {
                    value = GetValue(Instance);
                }

                return value;
            }
            set
            {
                if (IsEnumerable)
                {
                    var list = Instance as IEnumerable;
                    if (list == null)
                    {
                        throw new InvalidOperationException("Instance should be a list.");
                    }
                    foreach (object item in list)
                    {
                        SetValue(item, value);
                    }
                }
                else
                {
                    OldValue = Value;
                    SetValue(Instance, value);
                }
                //  NotifyPropertyChanged("Value");
            }
        }

        public object OldValue { get; set; }

I'm not sure what to set OldValue to when Value is Enumerable. Any suggestions?
Coordinator
Feb 8, 2011 at 7:00 AM

thank you! Bugfixes like this is exactly what I hoped for when publishing the project on codeplex!

I submitted your changes, the event should be raised only once, and include the oldvalue. 

For multi-object editing (using SelectedObjects) we could store the old value for each object (maybe use a Dictionary<object,object> (key: object, value: oldValue)) and pass this with the PropertyChanged event args?