Почему никто не использует INotifyPropertyChanging? - PullRequest
13 голосов
/ 03 ноября 2011

Я знаю, что MVVM интенсивно использует INotifyPropertyChanged, но я никогда не видел использования INotifyPropertyChanging.Любая причина почему?

Если бы я хотел использовать это, что было бы хорошим способом интегрировать это в мою MVVM Framework?Я знаю, что вы не должны использовать MessageBox в своей модели представления, потому что тогда вы не можете выполнить его модульное тестирование.Итак, как можно было бы выдать предупреждение, а затем продолжить с PropertyChange, если это применимо?

Ответы [ 5 ]

12 голосов
/ 03 ноября 2011

Что нужно помнить о INotifyPropertyChanging, так это то, что вы не можете остановить изменение не произойдет. Это просто позволяет вам записать, что изменение произошло.

Я использую его в своей структуре для отслеживания изменений, но он не подходит для остановки изменений.

Вы можете расширить ViewModelBase с помощью пользовательского интерфейса / пары событий:

delegate void AcceptPendingChangeHandler(
    object sender,
    AcceptPendingChangeEventArgs e);

interface IAcceptPendingChange
{
    AcceptPendingChangeHandler PendingChange;
}

class AcceptPendingChangeEventArgs : EventArgs
{
    public string PropertyName { get; private set; }
    public object NewValue { get; private set; }
    public bool CancelPendingChange { get; set; }
    // flesh this puppy out
}

class ViewModelBase : IAcceptPendingChange, ...
{
    protected virtual bool RaiseAcceptPendingChange(
        string propertyName,
        object newValue)
    {
        var e = new AcceptPendingChangeEventArgs(propertyName, newValue)
        var handler = this.PendingChange;
        if (null != handler)
        {
            handler(this, e);
        }

        return !e.CancelPendingChange;
    }
}

На этом этапе вам необходимо добавить его по соглашению к моделям вашего представления:

class SomeViewModel : ViewModelBase
{
     public string Foo
     {
         get { return this.foo; }
         set
         {
             if (this.RaiseAcceptPendingChange("Foo", value))
             {
                 this.RaiseNotifyPropertyChanging("Foo");
                 this.foo = value;
                 this.RaiseNotifyPropretyChanged("Foo");
             }
         }
     }
}
4 голосов
/ 04 января 2017

INotifyPropertyChanging - это оптимизация для использования с Linq to SQL. Когда объект реализует этот интерфейс, он использует событие изменения в качестве сигнала для кэширования старого значения свойства. Если объект не реализует этот интерфейс, он всегда будет кэшировать значения свойств, увеличивая использование памяти. См. Как интерфейс INotifyPropertyChanging помогает ограничить потребление памяти для получения дополнительной информации.

1 голос
/ 03 ноября 2011

Чтобы ответить на второй вопрос, вы всегда можете использовать шаблон внедрения зависимостей, чтобы ваша виртуальная машина полагалась на интерфейс (INotifier?) И передавала конкретную реализацию, которая вызывает всплывающие сообщения.Это оставляет единичную тестируемость неизменной.

Редактировать: Первый вопрос, вероятно, слишком субъективен для SO.Цель интерфейса ясна, но когда его использовать, это будет для очень конкретных случаев использования.Свойства зависимостей приводят к чему-то похожему, и это может быть полезно для проверки того, что новое значение действительно перед его применением, но если вы используете простые свойства, то вы могли бы проще поместить эту проверку в свой установщик.Если другой компонент должен проверить достоверность, то, как правило, было бы проще, если бы этот компонент сам внес изменение (после проверки нового значения) или был вызван явно для проверки изменения компонентом, сделавшим изменение.

0 голосов
/ 17 октября 2013

INotifyPropertyChanging вызывается непосредственно перед изменением свойства. Важно почему? Так что внешний обработчик события может выдать исключение и предотвратить изменение. И почему вы хотите это сделать? Когда-нибудь это может стать вашим единственным решением проблемы с чужой кодовой базой, поэтому не спешите удалять аварийный люк.

0 голосов
/ 03 ноября 2011

Например, вам нужен INotifyPropertyChanged, если вы хотите знать, когда будет изменена любая переменная, потому что вы можете использовать PropertyChangedEventHandler. Таким образом, вы можете перезагрузить графический интерфейс во время работы программы, если есть какое-либо свойство зависимости, связанное с любым элементом графического интерфейса.

Что касается последнего вопроса, я думаю, что вы можете написать файл журнала с вашими определенными сообщениями, и если вы хотите показать пользователю любое предупреждение, вы можете использовать элементы управления, такие как сводка ошибок или всплывающие подсказки. Но если вам нужно только это для тестирования, вы можете держать предупреждения под блокировками try и catch.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...