Search code examples
mvvmprismmvvm-light

Difference between Set() and RaisePropertyChanged()


I am reading this http://msdn.microsoft.com/en-us/magazine/jj651572.aspx to learn mvvm light framework. I download the source code Friend.cs.

My question is why some set method of different property are implemented differently.

For example, the setter for First name is, why I need 'ref' keyword for _firstName.

 Set(FirstNamePropertyName, ref _firstName, value);

And the setter for DateOfBirthString is "

RaisePropertyChanged(() => DateOfBirth);

When will the linq expression will be evaluated?

namespace MyFriends.Model
{
    [SimpleSerialize]
    public class Friend : ObservableObject
    {
        /// <summary>
        /// The <see cref="FirstName" /> property's name.
        /// </summary>
        public const string FirstNamePropertyName = "FirstName";

        private string _firstName;

        /// <summary>
        /// Sets and gets the FirstName property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        [SimpleSerialize(FieldName = "first_name")]
        public string FirstName
        {
            get
            {
                return _firstName;
            }
            set
            {
                Set(FirstNamePropertyName, ref _firstName, value);
            }
        }

        /// <summary>
        /// The <see cref="LastName" /> property's name.
        /// </summary>
        public const string LastNamePropertyName = "LastName";

        private string _lastName;

        /// <summary>
        /// Sets and gets the LastName property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        [SimpleSerialize(FieldName = "last_name")]
        public string LastName
        {
            get
            {
                return _lastName;
            }
            set
            {
                Set(LastNamePropertyName, ref _lastName, value);
            }
        }

        /// <summary>
        /// The <see cref="DateOfBirth" /> property's name.
        /// </summary>
        public const string DateOfBirthPropertyName = "DateOfBirth";

        private string _dateOfBirthString;

        /// <summary>
        /// Sets and gets the DateOfBirth property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        [SimpleSerialize(FieldName = "birthday")]
        public string DateOfBirthString
        {
            get
            {
                return _dateOfBirthString;
            }
            set
            {
                _dateOfBirthString = value;
                RaisePropertyChanged(() => DateOfBirth);
            }
        }

        public DateTime DateOfBirth
        {
            get
            {
                if (string.IsNullOrEmpty(_dateOfBirthString))
                {
                    return DateTime.MinValue;
                }

                return DateTime.ParseExact(DateOfBirthString, "d", CultureInfo.InvariantCulture);
            }
            set
            {
                _dateOfBirthString = value.ToString("d", CultureInfo.InvariantCulture);
            }
        }

        private string _imageUrl;

        [SimpleSerialize(FieldName = "picture")]
        public string ImageUrl
        {
            get
            {
                return _imageUrl;
            }
            set
            {
                _imageUrl = value;
                RaisePropertyChanged(() => ImageUri);
            }
        }

        public Uri ImageUri
        {
            get
            {
                return new Uri(_imageUrl);
            }
        }
    }
}

Solution

  • The difference between those two methods is that the Set method replaces the old value of the _firstName field and then raises the PropertyChanged event, while the RaisePropertyChanged only raises the PropertyChanged event.

    You'll want to use the Set method in most cases, since it helps to shorten property declarations by wrapping all that typically needs to be done within a property's setter in just one method:

    1. It updates the value of the passed field and overwrites it with the content of value, and then
    2. raises the PropertyChanged event to notify Views about this update.

    The reason the field needs to be passed by reference (thus using ref _firstName) is that not the field's content is needed within the Set method, but the field itself is actually updated.

    The RaisePropertyChanged method is useful when an update of one property does also affect additional properties. In this case, these properties' contents need to be updated manually, then the RaisePropertyChanged method can be called to inform Views about which properties have actually changed.