How do "dirty checking" with a Windows Form? | | |
How do I check in a Windows Forms app if any controls have changed? I have
a form that collects data, and I want to prompt the user if they try to exit
the app, or load a new file, without saving changes that have been made.
In MFC/Win32, you'd trap the WM_COMMAND/EN_CHANGE notification messages,
etc. But, this doesn't seem to happen in Windows Forms. I tried Spy-ing a
windows forms app, and the WM_COMMAND messages don't even get sent (!).
Thanks!
- Dave | | | | re: How do "dirty checking" with a Windows Form?
Have event handlers on the controls. Multiple controls can all call the same
event handler.
"Dave" <dpt@nospam.eliassen.com> wrote in message
news:uy$A1EQvEHA.1392@TK2MSFTNGP14.phx.gbl...[color=blue]
> How do I check in a Windows Forms app if any controls have changed? I
> have
> a form that collects data, and I want to prompt the user if they try to
> exit
> the app, or load a new file, without saving changes that have been made.
>
> In MFC/Win32, you'd trap the WM_COMMAND/EN_CHANGE notification messages,
> etc. But, this doesn't seem to happen in Windows Forms. I tried Spy-ing
> a
> windows forms app, and the WM_COMMAND messages don't even get sent (!).
>
> Thanks!
>
> - Dave
>
>[/color] | | | | re: How do "dirty checking" with a Windows Form?
Ok, but I'm using standard controls. Isn't there a standard notification
event that controls send to their parent in Windows Forms, notifying the
parent that the control has changed? I'm pretty sure there must be an easy
way to do this - there is in Win32, and I doubt they'd have gotten rid of
such basic functionality when it was wrapped with .net.
"Bonj" <benjtaylor at hotpop d0t com> wrote in message
news:%23ecBLxSvEHA.2616@TK2MSFTNGP10.phx.gbl...[color=blue]
> Have event handlers on the controls. Multiple controls can all call the[/color]
same[color=blue]
> event handler.
>
> "Dave" <dpt@nospam.eliassen.com> wrote in message
> news:uy$A1EQvEHA.1392@TK2MSFTNGP14.phx.gbl...[color=green]
> > How do I check in a Windows Forms app if any controls have changed? I
> > have
> > a form that collects data, and I want to prompt the user if they try to
> > exit
> > the app, or load a new file, without saving changes that have been made.
> >
> > In MFC/Win32, you'd trap the WM_COMMAND/EN_CHANGE notification messages,
> > etc. But, this doesn't seem to happen in Windows Forms. I tried[/color][/color]
Spy-ing[color=blue][color=green]
> > a
> > windows forms app, and the WM_COMMAND messages don't even get sent (!).
> >
> > Thanks!
> >
> > - Dave
> >
> >[/color]
>
>[/color] | | | | re: How do "dirty checking" with a Windows Form?
I dont know about Win32, but as bonj says what you want can be done simply
by suscribing a standard event handler to each controls changed event (or
relevent event for that control). Use a private bool to remember the state.
You are writing about 5 lines of code (and one for each new control added to
the form) simple e.g.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace WindowsApplication6
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private bool dataChanged = false;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.Button buttonClose;
private System.Windows.Forms.Button buttonSave;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.textBox2 = new System.Windows.Forms.TextBox();
this.buttonClose = new System.Windows.Forms.Button();
this.buttonSave = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(32, 32);
this.textBox1.Name = "textBox1";
this.textBox1.TabIndex = 0;
this.textBox1.Text = "textBox1";
this.textBox1.TextChanged += new
System.EventHandler(this.formControlChanged);
//
// textBox2
//
this.textBox2.Location = new System.Drawing.Point(32, 72);
this.textBox2.Name = "textBox2";
this.textBox2.TabIndex = 1;
this.textBox2.Text = "textBox2";
this.textBox2.TextChanged += new
System.EventHandler(this.formControlChanged);
//
// buttonClose
//
this.buttonClose.Location = new System.Drawing.Point(192, 216);
this.buttonClose.Name = "buttonClose";
this.buttonClose.TabIndex = 2;
this.buttonClose.Text = "&Close";
this.buttonClose.Click += new
System.EventHandler(this.buttonClose_Click);
//
// buttonSave
//
this.buttonSave.Location = new System.Drawing.Point(112, 216);
this.buttonSave.Name = "buttonSave";
this.buttonSave.TabIndex = 3;
this.buttonSave.Text = "&Save";
this.buttonSave.Click += new System.EventHandler(this.buttonSave_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.buttonSave);
this.Controls.Add(this.buttonClose);
this.Controls.Add(this.textBox2);
this.Controls.Add(this.textBox1);
this.Name = "Form1";
this.Text = "Form1";
this.Closing += new
System.ComponentModel.CancelEventHandler(this.Form 1_Closing);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void formControlChanged(object sender, System.EventArgs e)
{
this.dataChanged = true;
}
private void buttonClose_Click(object sender, System.EventArgs e)
{
this.Close();
}
private void Form1_Closing(object sender,
System.ComponentModel.CancelEventArgs e)
{
if (this.dataChanged)
{
e.Cancel = true;
MessageBox.Show("Warning! Data has changed and must be saved");
}
}
private void buttonSave_Click(object sender, System.EventArgs e)
{
//data saved
this.dataChanged = false;
}
}
}
"Dave" <dpt@nospam.eliassen.com> wrote in message
news:OQ0X89SvEHA.4076@TK2MSFTNGP14.phx.gbl...[color=blue]
> Ok, but I'm using standard controls. Isn't there a standard notification
> event that controls send to their parent in Windows Forms, notifying the
> parent that the control has changed? I'm pretty sure there must be an
> easy
> way to do this - there is in Win32, and I doubt they'd have gotten rid of
> such basic functionality when it was wrapped with .net.
>
> "Bonj" <benjtaylor at hotpop d0t com> wrote in message
> news:%23ecBLxSvEHA.2616@TK2MSFTNGP10.phx.gbl...[color=green]
>> Have event handlers on the controls. Multiple controls can all call the[/color]
> same[color=green]
>> event handler.
>>
>> "Dave" <dpt@nospam.eliassen.com> wrote in message
>> news:uy$A1EQvEHA.1392@TK2MSFTNGP14.phx.gbl...[color=darkred]
>> > How do I check in a Windows Forms app if any controls have changed? I
>> > have
>> > a form that collects data, and I want to prompt the user if they try to
>> > exit
>> > the app, or load a new file, without saving changes that have been
>> > made.
>> >
>> > In MFC/Win32, you'd trap the WM_COMMAND/EN_CHANGE notification
>> > messages,
>> > etc. But, this doesn't seem to happen in Windows Forms. I tried[/color][/color]
> Spy-ing[color=green][color=darkred]
>> > a
>> > windows forms app, and the WM_COMMAND messages don't even get sent (!).
>> >
>> > Thanks!
>> >
>> > - Dave
>> >
>> >[/color]
>>
>>[/color]
>
>[/color] | | | | re: How do "dirty checking" with a Windows Form?
Thanks, Mark. Yes, I finally figured out pretty much the same thing. Kind
of a hassle if you have lots of controls, though. In Win32, the controls
are sending the change event to the parent without having to subscribe.
Easier. There is an easier way than having a separate handler for each
control, though - you can use the same handler for each control of the same
type.
- Dave
"Mark Broadbent" <nospam@nospam.com> wrote in message
news:Oreg7PVvEHA.2536@TK2MSFTNGP11.phx.gbl...[color=blue]
> I dont know about Win32, but as bonj says what you want can be done simply
> by suscribing a standard event handler to each controls changed event (or
> relevent event for that control). Use a private bool to remember the[/color]
state.[color=blue]
> You are writing about 5 lines of code (and one for each new control added[/color]
to[color=blue]
> the form) simple e.g.
>
> using System;
> using System.Drawing;
> using System.Collections;
> using System.ComponentModel;
> using System.Windows.Forms;
> using System.Data;
>
> namespace WindowsApplication6
> {
> /// <summary>
> /// Summary description for Form1.
> /// </summary>
> public class Form1 : System.Windows.Forms.Form
> {
> private bool dataChanged = false;
> private System.Windows.Forms.TextBox textBox1;
> private System.Windows.Forms.TextBox textBox2;
> private System.Windows.Forms.Button buttonClose;
> private System.Windows.Forms.Button buttonSave;
> /// <summary>
> /// Required designer variable.
> /// </summary>
> private System.ComponentModel.Container components = null;
>
> public Form1()
> {
> //
> // Required for Windows Form Designer support
> //
> InitializeComponent();
>
> //
> // TODO: Add any constructor code after InitializeComponent call
> //
> }
>
> /// <summary>
> /// Clean up any resources being used.
> /// </summary>
> protected override void Dispose( bool disposing )
> {
> if( disposing )
> {
> if (components != null)
> {
> components.Dispose();
> }
> }
> base.Dispose( disposing );
> }
>
> #region Windows Form Designer generated code
> /// <summary>
> /// Required method for Designer support - do not modify
> /// the contents of this method with the code editor.
> /// </summary>
> private void InitializeComponent()
> {
> this.textBox1 = new System.Windows.Forms.TextBox();
> this.textBox2 = new System.Windows.Forms.TextBox();
> this.buttonClose = new System.Windows.Forms.Button();
> this.buttonSave = new System.Windows.Forms.Button();
> this.SuspendLayout();
> //
> // textBox1
> //
> this.textBox1.Location = new System.Drawing.Point(32, 32);
> this.textBox1.Name = "textBox1";
> this.textBox1.TabIndex = 0;
> this.textBox1.Text = "textBox1";
> this.textBox1.TextChanged += new
> System.EventHandler(this.formControlChanged);
> //
> // textBox2
> //
> this.textBox2.Location = new System.Drawing.Point(32, 72);
> this.textBox2.Name = "textBox2";
> this.textBox2.TabIndex = 1;
> this.textBox2.Text = "textBox2";
> this.textBox2.TextChanged += new
> System.EventHandler(this.formControlChanged);
> //
> // buttonClose
> //
> this.buttonClose.Location = new System.Drawing.Point(192, 216);
> this.buttonClose.Name = "buttonClose";
> this.buttonClose.TabIndex = 2;
> this.buttonClose.Text = "&Close";
> this.buttonClose.Click += new
> System.EventHandler(this.buttonClose_Click);
> //
> // buttonSave
> //
> this.buttonSave.Location = new System.Drawing.Point(112, 216);
> this.buttonSave.Name = "buttonSave";
> this.buttonSave.TabIndex = 3;
> this.buttonSave.Text = "&Save";
> this.buttonSave.Click += new[/color]
System.EventHandler(this.buttonSave_Click);[color=blue]
> //
> // Form1
> //
> this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
> this.ClientSize = new System.Drawing.Size(292, 266);
> this.Controls.Add(this.buttonSave);
> this.Controls.Add(this.buttonClose);
> this.Controls.Add(this.textBox2);
> this.Controls.Add(this.textBox1);
> this.Name = "Form1";
> this.Text = "Form1";
> this.Closing += new
> System.ComponentModel.CancelEventHandler(this.Form 1_Closing);
> this.ResumeLayout(false);
>
> }
> #endregion
>
> /// <summary>
> /// The main entry point for the application.
> /// </summary>
> [STAThread]
> static void Main()
> {
> Application.Run(new Form1());
> }
>
> private void formControlChanged(object sender, System.EventArgs e)
> {
> this.dataChanged = true;
> }
>
> private void buttonClose_Click(object sender, System.EventArgs e)
> {
> this.Close();
> }
>
> private void Form1_Closing(object sender,
> System.ComponentModel.CancelEventArgs e)
> {
> if (this.dataChanged)
> {
> e.Cancel = true;
> MessageBox.Show("Warning! Data has changed and must be saved");
> }
>
> }
>
> private void buttonSave_Click(object sender, System.EventArgs e)
> {
> //data saved
> this.dataChanged = false;
> }
>
> }
> }
>
>
>
> "Dave" <dpt@nospam.eliassen.com> wrote in message
> news:OQ0X89SvEHA.4076@TK2MSFTNGP14.phx.gbl...[color=green]
> > Ok, but I'm using standard controls. Isn't there a standard[/color][/color]
notification[color=blue][color=green]
> > event that controls send to their parent in Windows Forms, notifying the
> > parent that the control has changed? I'm pretty sure there must be an
> > easy
> > way to do this - there is in Win32, and I doubt they'd have gotten rid[/color][/color]
of[color=blue][color=green]
> > such basic functionality when it was wrapped with .net.
> >
> > "Bonj" <benjtaylor at hotpop d0t com> wrote in message
> > news:%23ecBLxSvEHA.2616@TK2MSFTNGP10.phx.gbl...[color=darkred]
> >> Have event handlers on the controls. Multiple controls can all call the[/color]
> > same[color=darkred]
> >> event handler.
> >>
> >> "Dave" <dpt@nospam.eliassen.com> wrote in message
> >> news:uy$A1EQvEHA.1392@TK2MSFTNGP14.phx.gbl...
> >> > How do I check in a Windows Forms app if any controls have changed?[/color][/color][/color]
I[color=blue][color=green][color=darkred]
> >> > have
> >> > a form that collects data, and I want to prompt the user if they try[/color][/color][/color]
to[color=blue][color=green][color=darkred]
> >> > exit
> >> > the app, or load a new file, without saving changes that have been
> >> > made.
> >> >
> >> > In MFC/Win32, you'd trap the WM_COMMAND/EN_CHANGE notification
> >> > messages,
> >> > etc. But, this doesn't seem to happen in Windows Forms. I tried[/color]
> > Spy-ing[color=darkred]
> >> > a
> >> > windows forms app, and the WM_COMMAND messages don't even get sent[/color][/color][/color]
(!).[color=blue][color=green][color=darkred]
> >> >
> >> > Thanks!
> >> >
> >> > - Dave
> >> >
> >> >
> >>
> >>[/color]
> >
> >[/color]
>
>[/color] | | | | re: How do "dirty checking" with a Windows Form?
Yes you are right (my code only used one handler for each of the textboxes).
There is a slightly easier way to implement this (if you have loads of
controls) and that would be to loop through the forms control collection and
assign the delegate handler to each (conditionally if required). You could
therefore write a reusable bit of code to do this.
Anyhow good luck with the coding.
Br,
Mark.
"Dave T" <dpt@eliassen.XXcomXX> wrote in message
news:ujEWMPivEHA.1260@TK2MSFTNGP12.phx.gbl...[color=blue]
> Thanks, Mark. Yes, I finally figured out pretty much the same thing.
> Kind
> of a hassle if you have lots of controls, though. In Win32, the controls
> are sending the change event to the parent without having to subscribe.
> Easier. There is an easier way than having a separate handler for each
> control, though - you can use the same handler for each control of the
> same
> type.
>
> - Dave
> "Mark Broadbent" <nospam@nospam.com> wrote in message
> news:Oreg7PVvEHA.2536@TK2MSFTNGP11.phx.gbl...[color=green]
>> I dont know about Win32, but as bonj says what you want can be done
>> simply
>> by suscribing a standard event handler to each controls changed event (or
>> relevent event for that control). Use a private bool to remember the[/color]
> state.[color=green]
>> You are writing about 5 lines of code (and one for each new control added[/color]
> to[color=green]
>> the form) simple e.g.
>>
>> using System;
>> using System.Drawing;
>> using System.Collections;
>> using System.ComponentModel;
>> using System.Windows.Forms;
>> using System.Data;
>>
>> namespace WindowsApplication6
>> {
>> /// <summary>
>> /// Summary description for Form1.
>> /// </summary>
>> public class Form1 : System.Windows.Forms.Form
>> {
>> private bool dataChanged = false;
>> private System.Windows.Forms.TextBox textBox1;
>> private System.Windows.Forms.TextBox textBox2;
>> private System.Windows.Forms.Button buttonClose;
>> private System.Windows.Forms.Button buttonSave;
>> /// <summary>
>> /// Required designer variable.
>> /// </summary>
>> private System.ComponentModel.Container components = null;
>>
>> public Form1()
>> {
>> //
>> // Required for Windows Form Designer support
>> //
>> InitializeComponent();
>>
>> //
>> // TODO: Add any constructor code after InitializeComponent call
>> //
>> }
>>
>> /// <summary>
>> /// Clean up any resources being used.
>> /// </summary>
>> protected override void Dispose( bool disposing )
>> {
>> if( disposing )
>> {
>> if (components != null)
>> {
>> components.Dispose();
>> }
>> }
>> base.Dispose( disposing );
>> }
>>
>> #region Windows Form Designer generated code
>> /// <summary>
>> /// Required method for Designer support - do not modify
>> /// the contents of this method with the code editor.
>> /// </summary>
>> private void InitializeComponent()
>> {
>> this.textBox1 = new System.Windows.Forms.TextBox();
>> this.textBox2 = new System.Windows.Forms.TextBox();
>> this.buttonClose = new System.Windows.Forms.Button();
>> this.buttonSave = new System.Windows.Forms.Button();
>> this.SuspendLayout();
>> //
>> // textBox1
>> //
>> this.textBox1.Location = new System.Drawing.Point(32, 32);
>> this.textBox1.Name = "textBox1";
>> this.textBox1.TabIndex = 0;
>> this.textBox1.Text = "textBox1";
>> this.textBox1.TextChanged += new
>> System.EventHandler(this.formControlChanged);
>> //
>> // textBox2
>> //
>> this.textBox2.Location = new System.Drawing.Point(32, 72);
>> this.textBox2.Name = "textBox2";
>> this.textBox2.TabIndex = 1;
>> this.textBox2.Text = "textBox2";
>> this.textBox2.TextChanged += new
>> System.EventHandler(this.formControlChanged);
>> //
>> // buttonClose
>> //
>> this.buttonClose.Location = new System.Drawing.Point(192, 216);
>> this.buttonClose.Name = "buttonClose";
>> this.buttonClose.TabIndex = 2;
>> this.buttonClose.Text = "&Close";
>> this.buttonClose.Click += new
>> System.EventHandler(this.buttonClose_Click);
>> //
>> // buttonSave
>> //
>> this.buttonSave.Location = new System.Drawing.Point(112, 216);
>> this.buttonSave.Name = "buttonSave";
>> this.buttonSave.TabIndex = 3;
>> this.buttonSave.Text = "&Save";
>> this.buttonSave.Click += new[/color]
> System.EventHandler(this.buttonSave_Click);[color=green]
>> //
>> // Form1
>> //
>> this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
>> this.ClientSize = new System.Drawing.Size(292, 266);
>> this.Controls.Add(this.buttonSave);
>> this.Controls.Add(this.buttonClose);
>> this.Controls.Add(this.textBox2);
>> this.Controls.Add(this.textBox1);
>> this.Name = "Form1";
>> this.Text = "Form1";
>> this.Closing += new
>> System.ComponentModel.CancelEventHandler(this.Form 1_Closing);
>> this.ResumeLayout(false);
>>
>> }
>> #endregion
>>
>> /// <summary>
>> /// The main entry point for the application.
>> /// </summary>
>> [STAThread]
>> static void Main()
>> {
>> Application.Run(new Form1());
>> }
>>
>> private void formControlChanged(object sender, System.EventArgs e)
>> {
>> this.dataChanged = true;
>> }
>>
>> private void buttonClose_Click(object sender, System.EventArgs e)
>> {
>> this.Close();
>> }
>>
>> private void Form1_Closing(object sender,
>> System.ComponentModel.CancelEventArgs e)
>> {
>> if (this.dataChanged)
>> {
>> e.Cancel = true;
>> MessageBox.Show("Warning! Data has changed and must be saved");
>> }
>>
>> }
>>
>> private void buttonSave_Click(object sender, System.EventArgs e)
>> {
>> //data saved
>> this.dataChanged = false;
>> }
>>
>> }
>> }
>>
>>
>>
>> "Dave" <dpt@nospam.eliassen.com> wrote in message
>> news:OQ0X89SvEHA.4076@TK2MSFTNGP14.phx.gbl...[color=darkred]
>> > Ok, but I'm using standard controls. Isn't there a standard[/color][/color]
> notification[color=green][color=darkred]
>> > event that controls send to their parent in Windows Forms, notifying
>> > the
>> > parent that the control has changed? I'm pretty sure there must be an
>> > easy
>> > way to do this - there is in Win32, and I doubt they'd have gotten rid[/color][/color]
> of[color=green][color=darkred]
>> > such basic functionality when it was wrapped with .net.
>> >
>> > "Bonj" <benjtaylor at hotpop d0t com> wrote in message
>> > news:%23ecBLxSvEHA.2616@TK2MSFTNGP10.phx.gbl...
>> >> Have event handlers on the controls. Multiple controls can all call
>> >> the
>> > same
>> >> event handler.
>> >>
>> >> "Dave" <dpt@nospam.eliassen.com> wrote in message
>> >> news:uy$A1EQvEHA.1392@TK2MSFTNGP14.phx.gbl...
>> >> > How do I check in a Windows Forms app if any controls have changed?[/color][/color]
> I[color=green][color=darkred]
>> >> > have
>> >> > a form that collects data, and I want to prompt the user if they try[/color][/color]
> to[color=green][color=darkred]
>> >> > exit
>> >> > the app, or load a new file, without saving changes that have been
>> >> > made.
>> >> >
>> >> > In MFC/Win32, you'd trap the WM_COMMAND/EN_CHANGE notification
>> >> > messages,
>> >> > etc. But, this doesn't seem to happen in Windows Forms. I tried
>> > Spy-ing
>> >> > a
>> >> > windows forms app, and the WM_COMMAND messages don't even get sent[/color][/color]
> (!).[color=green][color=darkred]
>> >> >
>> >> > Thanks!
>> >> >
>> >> > - Dave
>> >> >
>> >> >
>> >>
>> >>
>> >
>> >[/color]
>>
>>[/color]
>
>[/color] |  | Similar C# / C Sharp bytes | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,295 network members.
|