Need a good way to manage the status - the data has changed since the last save - with MVVM

Consider an application that is implemented using MVVM in which a user enters data.
When the user selects "open file", "new file", etc., the application asks the user if he wants to save the data to a file before invoking the requested command. However, if the user has not changed any data since the last save, the application should skip this question and continue directly when invoking the command. Note that only properties that end up owned by the model need to change status. For example, if a user has changed a selected item in the list (which changes the virtual machine), it does not need to be saved.

How would you implement such a requirement?
Manually raising an event when any property in the VM changes seems tedious and error prone.

Thanks, Elad

+2


source to share


2 answers


How do I use PostSharp?

I would create 2 attributes:

1. RaisePropertyChanged: INotifyPropertyChanged with postsharp



2. And a second similar one, which only sets the HasChanged flag:

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

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

    // ...
}

      

0


source


With MVVM (usually) every class must implement INotifyPropertyChanged, and every property setter must fire a property changed event:

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

      

Yes: it is error prone and even with some clever use of lambda, compiler support is not great. But what is MVVM to do and you can see why in most cases in MVVM.

However, to answer your question, I would recommend that you add some code to your FirePropertyChanged method:



    public bool HasChanged { get; set; }

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

      

And you need to remember to set HasChanged to false after you've finished reading an object from a file or database.

10 points if you can tell me why HasChanged doesn't fire PropertyChanged despite what I said above. This means, of course, that you shouldn't be using HasChanged from XAML

edit: There is a great example of this kind here: http://follesoe.no/silverlight/divelog/

+1


source







All Articles