Click here to Skip to main content
13,834,141 members
Click here to Skip to main content
Add your own
alternative version


80 bookmarked
Posted 28 Jun 2007
Licenced CPOL

Form Changed Control

, 26 May 2008
Rate this:
Please Sign up or sign in to vote.
A component that allows you to monitor all the controls on the form and list any that have changed (for dirty checking)


This control is a quick and dirty component (based on the System.ComponentModel.IExtenderProvider) that allows you to list all the components that have been changed, e.g. to allow you to decide whether a form needs to be saved.


This is a quick and dirty solution to the "how do I know if any data on my form has changed" problem. It allows you to alter the user interface to show that it has changed and also to decide what needs to be saved.

Screenshot - changed_textbox.jpg

Using the Code

The component has one property: ControlsThatHaveChanged that is a generic list of all the controls whose data has changed since the last reset. If this list isn't empty, then the form has changed and needs to be saved.

There is one method: ResetDirtyFlags which allows you to reset the list of controls that have changed - call this when the form is populated or the data are saved.

In addition, an event is raised whenever a control that is being monitored for changes is changed or changed back to its initial state.


 Private Sub FormChangedComponent1_FormControlChanged(ByVal sender As Object, _ 
         ByVal e As FormChangedEventArgs) _ 
         Handles FormChangedComponent1.FormControlChanged
    If TypeOf e.ControlChanged Is TextBox Then
        If e.Changed Then
            e.ControlChanged.BackColor = Color.Yellow
            e.ControlChanged.BackColor = Color.White
        End If
    End If
End Sub  


void formChangedComponent1_MonitoredControlChanged(object sender, FormChangedEventArgs e)
    if (e.ControlChanged is TextBox)
        if (e.Changed)
            e.ControlChanged.BackColor = Color.Yellow; 
            e.ControlChanged.BackColor = Color.White;

How It Works

The component implements the Implements System.ComponentModel.IExtenderProvider to extend the controls on a form and provides three new properties to each of these controls:

Screenshot - properties.jpg

MonitorForChanges - Set to True to monitor a control for changes

ChangeEventToMonitor - Set this to the name of the event to watch (e.g. "ValueChanged" or whichever for the control)

ValueNameToMonitor - Set this to the name of the property that represents the value of the control (e.g. "Text" for a textbox)

Note that these properties are case sensitive which can be a trap for the unwary.

Where a component has this extended property set to True, the component adds a handler to its "Changed" event specified and when that event fires, it updates an internal generic collection of the components that have changed.

The component can be reset (i.e. all controls are marked as unchanged) after a save event or when a record has been refreshed.


Public Sub SetMonitorForChanges(ByVal ctl As Control, ByVal value As Boolean)
    If value Then
        If Not _ControlChanged.ContainsKey(ctl) Then
            _ControlChanged.Add(ctl, False)
            Dim evi As System.Reflection.EventInfo
            evi = ctl.GetType.GetEvent(Me.GetChangeEventName(ctl))
            If Not (evi Is Nothing) Then
                '\\ Get the method that adds a handler to the changed event
                Dim mi As System.Reflection.MethodInfo
                mi = evi.GetAddMethod(False)
                '\\ add a handler to that changed event
                mi.Invoke(ctl, New Object() {Me.ChangeEventhandler})
            End If
        End If
        If _ControlChanged.ContainsKey(ctl) Then
        End If
    End If
End Sub


private void ResetMonitoringState()
    System.Reflection.EventInfo evi;
    Type ctlType = _ctlToMonitor.GetType();
    evi = ctlType.GetEvent(_ChangeEventName);
     if (_MonitoringEvent )
        // Remove the event handler from the control
        if ( evi != null)
            System.Reflection.MethodInfo mi = evi.GetRemoveMethod(false);
            mi.Invoke(_ctlToMonitor, new object[] { this.ChangeEventhandler() });
    if (_Monitor )
        // Add the event handler to the control
        if (evi != null)
            System.Reflection.MethodInfo mi = evi.GetAddMethod(false);
            mi.Invoke(_ctlToMonitor, new object[] { this.ChangeEventhandler() });
            _MonitoringEvent = true;


  • 2007-06-28
    • First release
  • 2007-07-03
    • Added properties to specify what event and value are being monitored and changed the code to do a true changed check using the hash value of the property
  • 2007-09-13
    • Added an event whenever a control being monitored changes or is changed back to its previous state
  • 2008-05-26
    • Added C# code version


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


About the Author

Duncan Edwards Jones
Software Developer (Senior)
Ireland Ireland
C# / SQL Server developer
Microsoft MVP (Azure) 2017
Microsoft MVP (Visual Basic) 2006, 2007

You may also be interested in...


Comments and Discussions

QuestionRadioButton Pin
D. Todorov12-Feb-18 21:50
memberD. Todorov12-Feb-18 21:50 
QuestionFields are getting a value at load time Pin
Member 818816713-Oct-14 4:46
memberMember 818816713-Oct-14 4:46 
AnswerRe: Fields are getting a value at load time Pin
Duncan Edwards Jones13-Oct-14 5:06
professionalDuncan Edwards Jones13-Oct-14 5:06 
GeneralRe: Fields are getting a value at load time Pin
Member 818816713-Oct-14 6:03
memberMember 818816713-Oct-14 6:03 
BugRe: Fields are getting a value at load time Pin
Duncan Edwards Jones13-Oct-14 6:14
professionalDuncan Edwards Jones13-Oct-14 6:14 
GeneralRe: Fields are getting a value at load time Pin
Member 818816713-Oct-14 7:09
memberMember 818816713-Oct-14 7:09 
QuestionVery nice work. Well done! Thank you for contributing. Pin
Member 37191026-Oct-13 6:44
memberMember 37191026-Oct-13 6:44 
GeneralProblems with some ValueToMonitor values Pin
Duncan Edwards Jones9-Jan-09 6:39
professionalDuncan Edwards Jones9-Jan-09 6:39 
QuestionGreat tool, how would I track original values? Pin
yarborg24-Jun-08 10:03
memberyarborg24-Jun-08 10:03 
AnswerRe: Great tool, how would I track original values? Pin
Duncan Edwards Jones24-Jun-08 10:32
professionalDuncan Edwards Jones24-Jun-08 10:32 
GeneralRe: Great tool, how would I track original values? Pin
yarborg24-Jun-08 10:42
memberyarborg24-Jun-08 10:42 
GeneralProblem with combo Box Change Pin
hardsoft26-May-08 17:57
memberhardsoft26-May-08 17:57 
GeneralRe: Problem with combo Box Change Pin
Duncan Edwards Jones26-May-08 23:48
professionalDuncan Edwards Jones26-May-08 23:48 
GeneralVB6 HELP Pin
morrisons28-Apr-08 12:55
membermorrisons28-Apr-08 12:55 
GeneralRe: VB6 HELP Pin
Duncan Edwards Jones28-Apr-08 21:03
professionalDuncan Edwards Jones28-Apr-08 21:03 
QuestionNice tool, but not all controls... Pin
necto3-Jul-07 0:48
membernecto3-Jul-07 0:48 
AnswerRe: Nice tool, but not all controls... [modified] Pin
Duncan Edwards Jones3-Jul-07 1:13
professionalDuncan Edwards Jones3-Jul-07 1:13 
QuestionVery Nice - How to change the default value? Pin
Dean_Rx29-Jun-07 7:28
professionalDean_Rx29-Jun-07 7:28 
AnswerRe: Very Nice - How to change the default value? Pin
Duncan Edwards Jones29-Jun-07 12:19
professionalDuncan Edwards Jones29-Jun-07 12:19 
AnswerRe: Very Nice - How to change the default value? Pin
Duncan Edwards Jones3-Jul-07 2:34
professionalDuncan Edwards Jones3-Jul-07 2:34 
GeneralGood work Pin
joebeam28-Jun-07 6:25
memberjoebeam28-Jun-07 6:25 
GeneralRe: Good work Pin
Duncan Edwards Jones28-Jun-07 6:44
professionalDuncan Edwards Jones28-Jun-07 6:44 
Generalisation would be tricky because you need to know (for any given control type) which event you are hooking in to.

You _could_ do a mapping in a configuration or resource file so that you can add new control types to the component and tell it which event to map to for that control.

Storing all the data to verify the form has really changed might be overkill - a checksum of the control's value, reset on the ResetDirtyFlags sub should be sufficient.

I'll put that on the todo list Wink | ;-)

Ex Datis:
Duncan Jones
Merrion Computing Ltd

GeneralRe: Good work Pin
Duncan Edwards Jones10-Jul-07 2:21
professionalDuncan Edwards Jones10-Jul-07 2:21 
GeneralRe: Good work Pin
joebeam10-Jul-07 9:43
memberjoebeam10-Jul-07 9:43 

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

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

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web05 | 2.8.190114.1 | Last Updated 26 May 2008
Article Copyright 2007 by Duncan Edwards Jones
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid