views:

106

answers:

2

I'm developing a winforms app with lots of different forms and user controls. Is there a recommended pattern that I could implement that notifies the user that there are unsaved changes on the current form/control when the form/control is exiting and also when the app is closing?

A: 
  1. Memento is a way to encapsulate undoable changes.

    You can then keep a log of your uncommitted memento instances.

    But that's usually way to complex.

  2. State is usually best.

    Your application has two "change" states: Saved All Changes, Unsaved Changes.

    Each State has a transition rule based on "change" and "save" methods.

    • The Saved All Changes implementation of "save" does nothing.

    • The Unsaved Changes implementation of "save" sets the state to "Saved All Changes".

    • The Saved All Changes implementation "change" sets the state to Unsaved Changes.

    • The Unsaved Changes implementation of "change" does nothing.

S.Lott
+1  A: 

I'm using LLBL Gen pro for the ORM so that has some good entity tracking built into the objects. I've kind of rolled my own that seems to work pretty well. I created a new interface that my base User Controls and base Forms implement:

public interface IClosingNotification
{
    /// <summary>
    /// True if there is a dirty entity (or a dirty entity in the collection) present
    /// </summary>
    bool DirtyEntityPresent { get; }
    /// <summary>
    /// Register an entity to be watched for changes
    /// </summary>
    /// <param name="entity"></param>
    void RegisterForClosingNotification(IEntity entity);
    /// <summary>
    /// Register a collection to be watched for changes
    /// </summary>
    /// <param name="collection"></param>
    void RegisterForClosingNotification(IEntityCollection collection);
    /// <summary>
    /// Returns true if the form should close without any notification
    /// </summary>
    /// <returns></returns>
    bool ShouldClose();
}

In my base control/form I have a collection of entities that I watch on each form, and I have a CloseForm() method in these classes that I use when a form is closing. In my forms, whenever I create an object I can then register it for closing notification using: RegisterForClosingNotification(MyCustomer);

It works well in our scenario.

Ciaran