Разница между Set() и RaisePropertyChanged()

Я читаю этот http://msdn.microsoft.com/en-us/magazine/jj651572.aspx, чтобы изучить фреймворк mvvm light. Я загружаю исходный код Friend.cs.

Мой вопрос в том, почему некоторые установленные методы разных свойств реализованы по-разному.

Например, сеттер для имени — это то, почему мне нужно ключевое слово «ref» для _firstName.

 Set(FirstNamePropertyName, ref _firstName, value);

И установщик для DateOfBirthString "

RaisePropertyChanged(() => DateOfBirth);

Когда будет оцениваться выражение linq?

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);
            }
        }
    }
}

person hap497    schedule 10.10.2014    source источник


Ответы (3)


Разница между этими двумя методами заключается в том, что метод Set заменяет старое значение поля _firstName, а затем вызывает событие PropertyChanged, а метод RaisePropertyChanged вызывает только событие PropertyChanged.

В большинстве случаев вы захотите использовать метод Set, так как он помогает сократить объявления свойств, заключая все, что обычно необходимо делать в установщике свойства, всего в один метод:

  1. Он обновляет значение переданного поля и перезаписывает его содержимым value, а затем
  2. вызывает событие PropertyChanged, чтобы уведомить Views об этом обновлении.

Причина, по которой поле должно передаваться по ссылке (таким образом, с использованием ref _firstName), заключается в том, что в методе Set требуется не содержимое поля, а само поле фактически обновляется.

Метод RaisePropertyChanged полезен, когда обновление одного свойства также влияет на другие свойства. В этом случае содержимое этих свойств необходимо обновить вручную, после чего можно вызвать метод RaisePropertyChanged, чтобы информировать представления о том, какие свойства фактически изменились.

person andreask    schedule 10.10.2014

В одном случае я обнаружил, что Set(ref _prop, value) не работает, когда вам нужно повторно отправить обновление или выполнить пользовательское сравнение. Set(ref _prop, value) сравнит _prop и значение для вас, но это может быть не то, что вы хотите. Для некоторых свойств я могу захотеть добавить еще несколько условий помимо простого сравнения, и в этом случае я установлю значение _prop = вручную, а затем сразу же подниму изменение;

Но в большинстве случаев я использую Set(ref _prop, value)

person beatnikthedan    schedule 01.04.2018

Вот фактическое использование, где IsRunning является основной операцией, но также вызывает уведомление об изменении свойства IsComplete, которое основано на IsRunning. Таким образом, оба свойства отправляют уведомление без отмены дополнительного кодирования.

private bool _IsRunning;

public bool IsRunning
{
    get => _IsRunning;
    set
    {
        SetProperty(ref _IsRunning, value);
        RaisePropertyChanged("IsComplete");
    }
}

public bool IsComplete => !IsRunning;
person ΩmegaMan    schedule 10.02.2020