A simple way to create this behavior is to track a "dirty" flag for the form, and trap the appropriate event on input controls to catch value changes. Rather than create an event handler for every input control, and write all that code again for the next form, a developer can create a simple helper class - one that assigns the appropriate event handling code for each of a form's input controls, and tracks the "dirty" state on behalf of the form. Such a class can then be reused across many forms and projects.
Here's a sample of such a class that demonstrates this simple technique.
public class FormDirtyTracker
{
private Form _frm;
private bool _isDirty;
// property denoting whether the tracked form is clean or dirty
public bool IsDirty
{
get { return _isDirty; }
set { _isDirty = value; }
}
// methods to make dirty or clean
public void SetAsDirty()
{
_isDirty = true;
}
public void SetAsClean()
{
_isDirty = false;
}
// initialize in the constructor by assigning event handlers
public FormDirtyTracker(Form frm)
{
_frm = frm;
AssignHandlersForControlCollection(frm.Controls);
}
// recursive routine to inspect each control and assign handlers accordingly
private void AssignHandlersForControlCollection(Control.ControlCollection coll)
{
foreach (Control c in coll)
{
if (c is TextBox)
(c as TextBox).TextChanged += new EventHandler(FormDirtyTracker_TextChanged);
if (c is CheckBox)
(c as CheckBox).CheckedChanged += new EventHandler(FormDirtyTracker_CheckedChanged);
// ... apply for other input types similarly ...
// recurively apply to inner collections
if (c.HasChildren)
AssignHandlersForControlCollection(c.Controls);
}
}
// event handlers
private void FormDirtyTracker_TextChanged(object sender, EventArgs e)
{
_isDirty = true;
}
private void FormDirtyTracker_CheckedChanged(object sender, EventArgs e)
{
_isDirty = true;
}
}
The class is instantiated in the form's Load handler like this:
private FormDirtyTracker _dirtyTracker;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// instantiate a tracker to determine if values have changed in the form
_dirtyTracker = new FormDirtyTracker(this);
}
Then when the form is closing, the developer can simply check
_dirtyTracker.IsDirty
to determine if the user should be prompted to save.This isn't a particularly sophisticated technique, and considers the document "dirty" with any change - even if the user changes a value back to its original. It does track user input however, is simple to code, and is reusable across multiple forms.
1 comments:
Exactly what I was looking for. Thanks!
Post a Comment
Submit a comment?