tags:

views:

27

answers:

2

What would be the cleanest way to have a Save state for an application so that whenever a property or content was updated the "Save" options would become enabled.

For example, there is a menu and toolbar "Save" buttons. When the WPF app first opens both buttons are disabled. When the user updates the properties or document, the buttons become enabled until a "Save" is done, at which point they go back to disabled.

+1  A: 

Bind IsEnabled to a ViewModel that exposes an "IsDirty" or "HasBeenModified" boolean property, or something of similar ilk. The ViewModel would watch for changes to the Model and set IsDirty to true if the Model is modified for any reason. When saved, the ViewModel can be told to set IsDirty to false, disabling the button.

You are using the Model-View-ViewModel pattern, right? Here are a few links on the pattern to help you on your way, just in case:

http://en.wikipedia.org/wiki/Model_View_ViewModel

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

http://www.wintellect.com/CS/blogs/jlikness/archive/2010/04/14/model-view-viewmodel-mvvm-explained.aspx

Randolpho
A: 

Are all the properties you wish to watch for in the same class? If so, something like this will work:

  1. Have the class derive from INotifyPropertyChanged;
  2. Watch for property changes from the class and set an IsDirty flag when there are changes
  3. Set IsEnabled for the Save button based on the IsDirty flag
  4. When the Save command is executed, set IsDirty=false

Notifying Class Example

public class NotifyingClass : INotifyPropertyChanged
{
        private string Property1Field;
        public string Property1
        {
            get { return this.Property1Field; }
            set { this.Property1Field = value; OnPropertyChanged("Property1"); }
        }

        private string Property2Field;
        public string Property2
        {
            get { return this.Property2Field; }
            set { this.Property2Field = value; OnPropertyChanged("Property2"); }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion
}

Watching for Property Changes

public partial class MainWindow : Window
{
    private bool isDirty;

    NotifyingClass MyProperties = new NotifyingClass();

    public MainWindow()
    {
        InitializeComponent();

        this.MyProperties.PropertyChanged += (s, e) =>
            {
                this.isDirty = true;
            };
    }
}

How you set the disabled/enabled state depends on what type of button/command implementation you are doing. If you would like further help just let me know how you are doing it (event handler, RoutedCommand, RelayCommand, other) and I'll check it out.

Jeremy