Click here to Skip to main content
Click here to Skip to main content
Go to top

Dirty Button

, 30 Aug 2007
Rate this:
Please Sign up or sign in to vote.
A button control that keeps track of the form’s dirty state.

Screenshot - dirtybutton.gif

Introduction

When you do a project where the user has to fill in a lot of information, you often want to know if there has been changes made or not so that you can enable a Save button accordingly. Normally, you would put a Boolean variable in your code (e.g., bDirtyBit) and enter some code in each control's Change event (e.g., bDirtyBit=True or cmdSave.Enabled=True).

In the project I'm currently working on, I've got forms with hundreds of controls, and entering code into each control's Change event is very tiresome. Plus, it's very easy to miss a control when you add new controls. Also, it's a lot of unnecessary code that makes the really important code harder to read.

So, I decided to do a special button control that can handle all that automatically for me without any coding (actually, somebody else suggested the idea, but didn't know how to implement it). And, that's what I did. The button is very basic. It keeps track of all the important controls on your form, and enables the button if a change has been made. Thus, it keeps your code free of all the abovementioned, unnecessary code.

The project also demonstrates how you can use an Extender Provider to add properties to other controls. It is a lot easier than you would think...

This is my first submission to The Code Project, so I hope everything is OK. If you encounter any problems, please don't hesitate to contact me.

Using the code

The use of the control is extremely simple. Just drop it on your form and add this code to the Form_Load event:

Private Sub Form1_Load(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles MyBase.Load

    DirtyButton1.StartMonitoring()

End Sub

These basic controls are monitored for changes: CheckBox, ComboBox, DateTimePicker, MaskedTextBox, MonthCalendar, NumericUpDown, RadioButton, RichTextBox, TextBox, Button (optional).

**** New in Version 2.0 ****

  • The button adds a property to the monitorable controls called DirtyMonitored (similar to the way the Tooltip component adds a ToolTip property). If you have a single control of the type above on the form (or more than one) that you do not want to include in the monitoring process, simply set that property to False – and voila: it is omitted.
  • Please note: These properties are not really added to the controls themselves. They are actually a part of the DirtyButton. So, they're only visible at design time. That means that you cannot use code like this: TextBox17.DirtyMonitored=True at runtime. You can call DirtyButton.SetDirtyMonitored(Textbox17), but it will have no effect if you do it after calling the StartMonitoring method. In that case, you will probably have to call EndMonitoring and then StartMonitoring again, but I haven't tried it, so I'm not 100% certain it works.

    And, these controls are not monitored (because from what criteria/event would we enable the button?): Label, LinkLabel, ListBox, ListView, NotifyIcon, PictureBox, ProgressBar, ToolTip, TreeView, and WebBrowser.

    You can set the dirty state manually if the controls above are changed in a way that you consider relevant, using:

    DirtyButton1.SetDirtyState()

    There are a few other methods and properties that are good to know: ResetDirtyState, IsDirty, SuspendMonitoring, ResumeMonitoring, SetDirtyOnButtonClick etc. All of these are practically self-explanatory, very simple to use, and the use is shown in the demo project.

  • I "accidentally" noticed that there was a bug in my initial control. If you place the DirtyButton in a GroupBox, it is only the controls nested in that GroupBox that are monitored. Not the controls outside or in other GroupBoxes. That is because I used the Parent property to determine where the DirtyButton was located, not the FindForm method.
  • But then I thought: well, maybe somebody likes it that way, and wants to have two or more GroupBoxes each with their own DirtyButton. Other people might want the button to monitor the whole form even if it's in a GroupBox.

    So, instead of fixing the bug, I simply made it a property of the button: MonitoringScope, which can be set to WholeForm or ParentOnly. That solved that problem!

  • I added a DirtyStateChanged event for the DirtyButton control. It fires when the button changes DirtyState, both when it becomes clean and when it becomes dirty. In the EventArgs, you get the state as a boolean plus the control that caused the change. In the demo project, you can see how you can find the name of that control.
  • I did some changes in the EndMonitoring routine. In version 1.0, I simply stopped monitoring the controls, but I left the event handlers where they where. In this version, I decided to do some cleaning up, and am now removing the event handlers.
  • Ulan Bator is no longer a country but a city... It is far away, though... Wink | ;-)

Possible improvements in upcoming versions

The ability to add custom and third party controls to the monitoring process would be nice, but was not necessary for me at this stage.

Collections for MonitoredControls, DirtyControls etc. as per request... Smile | :)

As it is now, controls that are added at runtime aren't included unless you call the StartMonitoring method after they are added. But, how often do you add controls at runtime?

History

  • 2.0: Bug fixes and new functions added. Please see the text above.
  • 1.0: Initial release.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Johnny J.
Software Developer (Senior)
Sweden Sweden
Born in Copenhagen, Denmark
Have been living in Paris, France and L.A., The United States
Now live in Stockholm, Sweden
 
Started programming when I got my first VIC 20, and a few months later on Commodore 64. Those were the days!
 
Studied programming at the Copenhagen Engineering Academy
 
Professional console, winforms and webforms programming in Comal, x86 Assembler, Fortran, Pascal, Delphi, Visual Basic 3 through 6, Classic ASP, C# and VB.NET
 
I now work as Senior .NET developer building Airline Booking Systems, and have a number of projects in various states of progress to work on in the spare time...
 
PS: The cat on my profile is one of my three cats, Ramses. He's all white, odd-eyed, deaf and definitely the coolest cat there is!

Comments and Discussions

 
GeneralAdd SelectedIndexChanged for ComboBoxes Pinmemberdreamgarden6-Nov-09 10:35 
QuestionI love this concept (How about a C# version) Pinmembersolaadio29-Oct-09 2:02 
AnswerRe: I love this concept (How about a C# version) PinmemberJohnny J.15-Apr-10 23:36 
GeneralVery Cool! Pinmemberhayes.adrian17-Sep-08 10:21 
GeneralTotal newb Pinmembersananelan28-Mar-08 10:07 
GeneralRe: Total newb PinmemberJohnny J.30-Mar-08 21:44 
What's the problem?
 
/Johnny J.
GeneralRe: Total newb Pinmembersananelan31-Mar-08 7:01 
GeneralJust a thought Pinmembermr_lasseter26-Jun-07 4:58 
GeneralRe: Just a thought PinmemberJohnny J.26-Jun-07 5:16 
GeneralRe: Just a thought Pinmembermr_lasseter26-Jun-07 9:09 
GeneralTha Tag is saved PinmemberJohnny J.26-Jun-07 4:07 
Questionsome suggestions Pinmember-tusk-17-Apr-07 15:51 
AnswerRe: some suggestions PinmemberJohnny J.18-Apr-07 3:51 
GeneralRe: some suggestions Pinmember-tusk-18-Apr-07 17:43 
QuestionWhat about? PinmemberCivilised Barbarian17-Apr-07 4:26 
AnswerRe: What about? PinmemberJohnny J.17-Apr-07 5:03 
AnswerRe: What about? PinmemberCivilised Barbarian25-Apr-07 1:40 
GeneralVery good.. PinmemberNaresh Mehta16-Apr-07 21:26 
GeneralBytheway Pinmembergdpaul12-Apr-07 9:56 
GeneralRe: Bytheway PinmemberJohnny J.12-Apr-07 10:51 
QuestionAnother Option? Pinmembergklesczewski12-Apr-07 8:13 
AnswerRe: Another Option? [modified] PinmemberJohnny J.12-Apr-07 9:19 
QuestionAny source code? Pinmemberellios12-Apr-07 0:53 
AnswerRe: Any source code? PinmemberJohnny J.12-Apr-07 3:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140916.1 | Last Updated 30 Aug 2007
Article Copyright 2007 by Johnny J.
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid