Событие для «попытки» изменения свойства

#.net #design-patterns #properties #event-log

#.net #шаблоны проектирования #свойства #журнал событий

Вопрос:

(с использованием .Net 3.5) У меня есть процедура, которая импортирует настройки из внешнего источника данных, после чего мне нужно отобразить псевдожурнал для пользователя с подробным описанием того, какие свойства были обновлены. Обычно я бы отслеживал обновления свойств через события property_changed. Однако, когда значение из источника данных оказывается уже равным значению свойства, событие property_changed никогда не вызывается, даже если был вызван набор свойств. Но мне все еще нужно отображать такие свойства для пользователя как «обновленные» из источника данных.

Какова общая схема здесь? Нужно ли мне другое событие (в дополнение к property_changed) в моих установщиках свойств — «property_attemptedset»?

Редактировать: Итак, одно из предложений заключается в том, что я просто не выполняю проверку равенства в установщике свойств, чтобы «property_changed» запускался независимо от того, что. Но мне всегда говорили фильтровать фактические изменения значений. Разве это не лучшая практика?

Комментарии:

1. расширил мой ответ на ваше редактирование.

Ответ №1:

Ну, довольно часто удается избежать возникновения события PropertyChanged, когда вы на самом деле не меняете значение свойства… но нет правила, в котором говорится, что вы должны. Просто удалите любую логику в установщике, которая проверяет новое значение на соответствие текущему значению.

Комментарии:

1. Да, мне всегда говорили избегать создания события PropertyChanged, если оно действительно не изменится. Уверены ли мы, что это действительно не имеет никакого значения для кода? И если это не имеет никакого значения, то почему мы должны делать это таким образом?

2. Разница в том, что весь ваш код обработки изменений будет выполняться (и пользовательский интерфейс придется обновлять) независимо от того, изменится свойство или нет. Если вы готовы принять это снижение производительности, тогда продолжайте.

Ответ №2:

если вы напишете свои свойства следующим образом:

 public string LastName{
    get { return lastName; }
    set {
        lastName = value;
        RaisePropertyChanged("LastName");
    }
}
  

Оно всегда должно запускать PropertyChanged -событие, даже если значение одно и то же. Для этого вам не нужно запускать какие-либо дополнительные события.

Редактировать

в дополнение к вашему редактированию: Да, считается лучшей практикой проверять фактические изменения значений, но если в вашем сценарии необходимо отслеживать изменения, не связанные с значениями, я не понимаю, почему вы не можете это изменить. «Лучшая практика» не означает «Нарушить это правило и отправиться в тюрьму», верно?
Но в случае, если у этих классов есть какие-либо другие наблюдатели, которые также полагаются на обычное поведение PropertyChanged, вы всегда можете расширить свойства и создать другое (пользовательское) событие, подобное упомянутому вами:

     public event PropertyChangedEventHandler AttemptedPropertyChanged;
    public void RaiseAttemptedPropertyChanged(string propName)
    {
        if (AttemptedPropertyChanged != null)
        {
            AttemptedPropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }


    public string LastName{
        get { return lastName; }
        set {                
            RaiseAttemptedPropertyChanged("LastName");
            if (lastName == value) return;
            lastName = value;
            RaisePropertyChanged("LastName");
        }
    }
  

Ответ №3:

Похоже, что ваш следующий шаг, основанный на том, что вы написали, — иногда предотвращать изменение. Если это так, я бы ввел новое событие, такое как BeforePropertySet , и передал объект события, который позволяет отменять.

Это соответствует лучшим практикам (предотвращая вероятность того, что кто-то когда-нибудь захочет использовать propertychanged обычным способом и не сможет понять, почему их код не работает), проясняет, что вы делаете, и позволяет вам немного лучше разделить проблемы.