Нужен хороший способ управления состоянием - изменились ли данные с момента последнего сохранения - под MVVM - PullRequest
2 голосов
/ 05 октября 2009

Рассмотрим приложение, которое реализовано с использованием MVVM, в котором пользователь вводит данные.
Когда пользователь выбирает «открыть файл», «новый файл» и т. Д., Приложение спрашивает пользователя, хочет ли он сохранить данные в файл, прежде чем вызывать запрошенную команду. Однако, если пользователь не изменил никаких данных со времени последнего сохранения, приложение должно пропустить этот вопрос и перейти непосредственно к вызову команды. Обратите внимание, что только свойства, которые в конечном итоге принадлежат модели, должны изменять статус. Например, если пользователь изменил выбранный элемент в списке (который изменяет виртуальную машину), он не требует сохранения.

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

Спасибо, Elad

Ответы [ 2 ]

1 голос
/ 05 октября 2009

В MVVM (обычно) каждый класс должен реализовывать INotifyPropertyChanged, и каждый установщик свойств должен вызывать событие изменения свойства:

public class Objective : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string _text;

    public string Text
    {
        get { return _text; }
        set
        {
            if (_text != value)
            {
                _text = value;
                FirePropertyChanged("Text");
            }
        }
    }

    private void FirePropertyChanged(string s)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(s));
        }
    }
}

Да: это подвержено ошибкам, и даже при некотором умном использовании lambda поддержка компилятора невелика. Но именно так нужно делать MVVM, и вы можете понять, почему в большинстве случаев знакомство с MVVM.

Однако, чтобы ответить на ваш вопрос, я бы порекомендовал вам просто добавить собственный код в ваш метод FirePropertyChanged:

    public bool HasChanged { get; set; }

    private void FirePropertyChanged(string s)
    {
        HasChanged = true;
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(s));
        }
    }

И вам нужно не забыть установить значение HasChanged в false после того, как вы закончили чтение объекта из файла или базы данных.

10 баллов, если вы можете сказать мне, почему HasChanged не запускает PropertyChanged, несмотря на то, что я сказал выше. Это означает, конечно, что вы не должны использовать HasChanged из XAML

edit: Здесь есть отличный пример такого рода вещей: http://follesoe.no/silverlight/divelog/

0 голосов
/ 06 октября 2009

Как насчет использования PostSharp?

Я бы создал 2 атрибута:

1. RaisePropertyChanged: INotifyProperty, изменено с резким

2. И второй аналогичный, который только устанавливает флаг HasChanged:

public class MainWindowViewModel : ViewModel
{
    [RaisePropertyChanged]
    public string Message { get; set; }

    [RaisePropertyChanged]
    [SetsHasChanged]
    public string DataThatCausesModifyDialog { get; set; }

    // ...
}
...