Click here to Skip to main content
6,596,602 members and growing! (19,944 online)
Email Password   helpLost your password?
Languages » VB.NET » Windows Forms     Intermediate

VB.NET Code Package: Keep Changed Data

By George B Gilbert

Add changed data protection to your forms in which the user can make changes to information.
VB, Windows, .NET, Visual Studio, Dev
Posted:18 Jan 2006
Views:37,384
Bookmarked:30 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
Prize winner in Competition "VB.NET Dec 2005"
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
7 votes for this article.
Popularity: 3.46 Rating: 4.10 out of 5

1

2
2 votes, 28.6%
3
2 votes, 28.6%
4
3 votes, 42.9%
5

Demo project

Message displayed when exiting and there are unsaved data changes

Contents

  • Introduction
  • Background
  • Double Text Users
    • Library Overview
    • Unwrapping The Library
    • Using The Library
      • Repeating The KeepChangedData Function
      • Protecting Changes To Data In A Form
        • Add And Initialize Flags
        • Set Data Changed Flag In Each Changeable Control
        • Reset Data Changed Flag When Data Saved
        • Test Data Changed Flag At Closing
  • Non-Double Text Users
    • Demo Project Summary
    • KeepChangedData Function Code
    • Code Needed For Each Form
      • Flag Declarations
      • Initialize Form Loading Flag
      • Initialize Data Changed Flag
      • Turn On Data Changed Flag
      • Turn Off Data Changed Flag
      • Test For Changes
  • Testing Your Code
  • Conclusion
  • Licensing And Limitation Of Liability

Introduction

This library contains the code needed to add changed data protection to your forms in which the user can make changes to information. The intent is to:

  1. keep track of whether or not any changes have been made, and then
  2. if the user tries to exit the form without first saving the changes, ask the user if those changes are to be saved.

When the user is queried about saving changes, the user is given the options to save the data at that point (and then continue to exit), not save the data (just exit), or cancel exiting the form.

Note: add the code for the KeepChangedData function to your project right after you start your project. Then add the data protection code to each form after each form has been otherwise completed. You will find it much easier to add this code to each form after you have added the code that saves the data. In addition, it is best if the saving of the data is done with one call to a function that returns true if the data is saved OK, and false if any error occurred that prevented the save.

Code is available in a package file for Double Text users, as well as in a demo project for non-Double Text users.

Background

I've been adding the Keep Changed Data code to my projects since I can't remember when. It probably goes back at least to VB 3. Now, the code has been updated to VB.NET and, with this Double Text library, I will continue to add data protection to my projects consistently and quickly.

Double Text Users

Library Overview

The Keep Changed Data (KCD) library consists of seven source files (.DbC) and an overview (.DbO). The KCD source files generate fully commented code that is ready to compile.

  • The code was written with Option Strict On
  • The repeated code has been tested multiple times
  • The code is fully commented
  • Region statements can be included or not included each time the KeepChangedData source file is repeated

Unwrapping The Library

  1. Download and unzip the package file. The package file is named Keep Changed Data.DbP.
  2. Unwrap the package in Double Text (File | Library Exchange | Unwrap). Save the library in an empty folder.

The library is ready to go. Repeat the code per the following instructions whenever you need to add data protection to a project. (If you don't like the way I've set up the source files, change them in the edit window.)

Using The Library

Repeating The KeepChangedData Function

The KeepChangedData function is added to a project once. Each time you need a copy of this function, follow these steps in Double Text:

  1. In the main window, press F12 and browse to the KCD library.
  2. Click on the "KeepChangedData Function" title.
  3. In the Region window, click the All button to select both items if you want the region statements included in your code, and then click OK. To exclude the region statements, just click OK.
  4. For the "Developer's name" prompt, enter your name and click OK (or press Enter). You can also just press Enter to accept the default name (mine).
  5. In the reminder window, click OK.

The source code is now on the clipboard. If you would like to review the code, press F4.

After the function code has been repeated, add it to your project.

  1. In Visual Studio, open an existing, or add a new module.
  2. Place the insertion cursor in the module where you want to add the KeepChangedData function.
  3. Press Ctrl^V.

Protecting Changes To Data In A Form

These steps are done for each form in your project in which information can be changed by the user. It is best if you add this code to each form after the form has been otherwise completed.

Add And Initialize Flags

When a form, in which data can be entered and/or changed, loads, one or more controls may need to be initialized with current or static data. This loading of current and static data will turn on the flag that keeps track of when data has been changed. It is important, therefore, to ensure that the data changed flag is turned off after the form is done loading and all initialization of controls is completed. I use another flag, that keeps track of when a form is loading, to ensure that the data changed flag is turned off before the user can begin making changes. If this initialization of the data changed flag is not done correctly, the user will be asked about saving changes even when no changes were made.

  • Repeat the "Flag Declarations" source file.
  • Place the code in the form's declarations section.
  • Repeat the "Initialize Form Loading Flag" source file.
  • Place the code at the beginning of the form load event.
  • Repeat the "Initialize Data Changed Flag" source file.
  • Place the code at the end of the form activated event.

Any code that is needed to initialize data in any controls is placed either in the form load event after the form loading flag is turned on, or in the form activated event before the data changed flag is turned off. The demo project has examples of both.

Set Data Changed Flag In Each Changeable Control

The data changed flag must be turned on in all control events that are fired when the information in the control is changed. This is normally a control's text changed or click related event depending on the control type. The appropriate event in which to turn on the data changed flag can usually be identified by double clicking on the control in the form design view. The event that is opened, or added in response to the double click on the control, should be where you want to turn on the data changed flag. The combo box is an exception. When you double click on a combo box in a form design view, the SelectedIndexChanged event is always opened in the code view. However, which event is appropriate for setting the data changed flag in a combo box (SelectedIndexChanged or TextChanged) depends on how you set the control's DropDownStyle property. Testing your data protection code (see below) is essential to ensuring that the data changed flag is being turned on and off correctly.

  • Repeat the "Turn On Data Changed Flag" source file.
  • Place the code in the appropriate event of all controls in which the user can change data.
Reset Data Changed Flag When Data Saved

The user, of course, should be able to save all data changes whenever he/she chooses. When data is saved, it is important to turn off the data changed flag so that the user is not bothered, when exiting a form, with a question about saving changes when there are no pending changes that haven't been saved.

  • Repeat the "Turn Off Data Changed Flag" source file.
  • Place the code in the procedure that saves the data after all the data has been successfully saved.
Test Data Change Flag At Closing

The last step is to test for unsaved changes when the user tries to exit the form.

  • Repeat the "Test For Changes" source file.
  • Place the code in the form closing event.

After placing this code, you must add the code to be executed when the user chooses to save the changes. This additional code is dependent on how you write the procedure that does the saving. There is sample code in the source text that illustrates one way to handle this situation.

All of the above instructions for using the library are in the library overview. Click on the Float button in the Double Text main window whenever you need a refresher. (If you change any of the source files, don't forget to reflect those changes in the overview.)

Non-Double Text Users

Demo Project Summary

Download and unzip the demo project. Open the solution in Visual Studio. When you need this code, use whichever tool you prefer to make a copy of the appropriate code, and then make any needed modifications.

Add the KeepChangedData function to your project right after you start your project. Then add the data protection code to each form after each form has been otherwise completed. You will find it much easier to add this code to each form after you have added the code that saves the data. It is best if the saving of the data is done with one call to a function that returns true if the data is saved OK, and false if any error occurred that prevented the save.

You might want to find and change the following, either before or after you paste the code into your project.

  • In the KeepChangedData function:
    • If you don't want the Region statements, delete them.
    • Change the date the code is added to your project.
    • Change the name of the developer.
  • In the test for changed data, add the code that is executed when the changes are to be saved.

KeepChangedData Function Code

Add this function to a project right after you start the project. Place the function in a module for global scope.

#Region " KeepChangedData function "
    Public Function KeepChangedData(ByVal callingForm As Form, _
                               ByVal dataChanged As Boolean, _
                               Optional ByVal altText As _
                               String = Nothing) As Integer
        '-----------------------------------------------------------

        ' Query the user as to whether or not

        ' the data changes made in a form are to be

        ' saved or discarded, or if the

        ' anticipated action is to be cancelled

        ' Pass:             callingForm     The form calling

                                            this function
        '                   dataChanged     Flag indicating whether

                                            or not any data
        '                                   changes have been made

        '                   altText         Optional question to be

                                            displayed other than
        '                                   "Save Changes?"

        ' Return:           0 = Keep changed data

        '                   1 = Do not keep changed data

        '                   2 = Cancel

        '-----------------------------------------------------------

        ' Date       Developer            Code Change

        ' ---------- -------------------- --------------------------

        ' 12/17/2005 G Gilbert            Original code

        '-----------------------------------------------------------


        '-----------------------------------------------------------

        ' Local Constant/Variable Declarations

        '-----------------------------------------------------------

        Dim QuestionText As String
        Dim Reply As Integer

        Const QMark As String = "?"

        '-----------------------------------------------------------

        ' Determine what the question text is to be

        '-----------------------------------------------------------

        If altText = Nothing Then
            QuestionText = "Save changes" & QMark
        Else
            QuestionText = altText
            '** Add a question mark, if needed

            If QuestionText.Substring(QuestionText.Length - 1) _
                                                   <> QMark Then
                QuestionText &= QMark
            End If
        End If

        '-----------------------------------------------------------

        ' Default to "do not keep changed data"

        ' (for those cases where no changes were

        ' made)

        '-----------------------------------------------------------

        Reply = 1

        '-----------------------------------------------------------

        ' If data has changed, ensure the form

        ' is active and not minimized. Then query

        ' the user as to what to do with the changed data.

        '-----------------------------------------------------------

        If dataChanged Then
            With callingForm
                If .WindowState = FormWindowState.Minimized Then
                    .WindowState = FormWindowState.Normal
                End If
                .Focus()
            End With
            Select Case MessageBox.Show(QuestionText, _
                                        "Data Changed", _
                                        MessageBoxButtons.YesNoCancel)
                Case DialogResult.Yes : Reply = 0
                Case DialogResult.Cancel : Reply = 2
            End Select
        End If

        '-----------------------------------------------------------

        ' Return user's selection

        '-----------------------------------------------------------

        Return Reply

    End Function
#End Region

Code Needed For Each Form

The code below is added to each form that contains controls in which the user can make changes to data.

Flag Declarations

Place this code in the form's declarations section:

Private _fbLoadingForm As Boolean
Private _fbDataChanged As Boolean

Initialize Form Loading Flag

Place this code at the beginning of the form load event before any other code:

'------------------------------------------------------

' Turn on the flag that indicates the form is loading

'------------------------------------------------------

_fbLoadingForm = True

Initialize Data Changed Flag

Place this code at the end of the form activate event after all other code:

'---------------------------------------

' Initialize the data changed flag

' and turn off the form loading flag

'---------------------------------------

If _fbLoadingForm Then
    _fbDataChanged = False
    _fbLoadingForm = False
End If

Turn On Data Changed Flag

Place this code in the appropriate event of all controls on the form that can be changed by the user. The appropriate event is that event that is fired whenever the information contained in the control is changed.

'--------------------------------

' Turn on the data changed flag

'--------------------------------

_fbDataChanged = True

Turn Off Data Changed Flag

Place this code in the function that saves the data on the form after the save has been successfully completed.

'--------------------------------

' Turn off the data changed flag

'--------------------------------

_fbDataChanged = False

Test For Changes

Place this code in the form's Closing event. Add code to be executed when the data changes are to be saved.

'-------------------------------------------------

' If there are pending changes, see if

' the user wants to discard or save them

' Return:      0 = Save changed data

'              1 = Do not save changed data

'              2 = Cancel exiting form

'-------------------------------------------------

Select Case KeepChangedData(Me, _fbDataChanged)
    Case 0       ' Keep changed data

        '

        ' Code to execute when the data

        ' is to be saved. For example, assuming

        ' you have a function named

        ' DataSavedOK that returns True or False to

        ' indicate whether or not data

        ' has been saved successfully, the code

        ' for this case could be as follows.

        '

        '   If Not DataSavedOK Then

        '       e.Cancel = True

        '   End If

        '

    Case 1       ' Do not keep the changed data

        '** Nothing to do ... fall through

    Case 2       ' Cancel exiting the form

        e.Cancel = True
End Select

Testing Your Code

A very important aspect of data protection in a form is that the protection works regardless of how a user elects to exit a form. This means, the data protection test has to be made whether the user clicks an Exit button, clicks Close in the form's control box menu, clicks the form's close button, or presses Alt^F4. Testing all of the exit paths from a form is essential to ensuring the data protection scheme is solid.

Testing a form's data protection code is lengthy, but, very necessary. Data protection code is worthless if it contains holes. Testing, therefore, means making sure that every control that can be changed is protected, and that the protection works regardless of how the user elects to exit the form.

Here're the minimal steps for testing your data protection code:

  • Check the data changed flag initialization
    • Open the form and immediately exit without making any changes (the Save Changes? message box should not appear).
  • Check setting of the data changed flag for all protected controls (loop through these steps at least once for each protected control)
    • Open the form.
    • Change a control (controls that can be changed in more than one way, like some combo boxes, have to be tested by making changes all possible ways one at a time in separate loops through these steps).
    • Exit the form (the Save Changes? message box should appear).
    • When exiting the form the first couple of times, click Yes, No, and Cancel in the message box until you are sure each button works correctly.
  • Check that saving the data resets the data changed flag
    • Open the form.
    • Change any of the protected controls.
    • Click the Save button.
    • Exit the form (the Save Changes? message box should not appear).
  • Test all of the form's exit routes (the Save Changes? message box should appear for any of the below exit options)
    • Open the form.
    • Change any of the protected controls.
    • Click the form's Close button (upper right corner).
    • Click Cancel.
    • Click the form's control box (upper left corner) and click the Close menu item.
    • Click Cancel.
    • Press Alt^F4.
    • Click Cancel.
    • Click the Exit or Close button you added to the form.

Conclusion

Losing data, or changes to data is very frustrating to users. Nothing will turn a user against an application faster than having spent time entering or modifying data only to have all the work lost because the user exited before clicking Save. Even the most intuitive, user friendly design will not salve the pain of having to do a lot of work over again. It is, therefore, imperative, in my opinion, that software developers incorporate air tight data protection into all of their projects. This is a large step towards making applications fault tolerant.


Licensing And Limitation Of Liability

You may use the Double Text library and all code offered in this article any way you choose without restriction.

Under no circumstances, and under no legal theory, tort, contract, or otherwise, will George Gilbert (hereafter referred to as "software author") or his licensors, be liable to the user of the Double Text library and all code offered in this article (hereafter referred to collectively as "article code") for any damages, including any lost profits, lost data, or other indirect, special, incidental, or consequential damages, arising out of the use or inability to use the article code, and data or information supplied, even if the software author, his licensors or authorized dealer have been advised of the possibility of such damages, or for any claim by any other party.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

George B Gilbert


Member
Click here to see a complete list of my articles.
Occupation: Software Developer
Company: 2 Good Software
Location: United States United States

Other popular VB.NET articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 8 of 8 (Total in Forum: 8) (Refresh)FirstPrevNext
Generalthankes Pinmembergoldman141510:51 24 Jun '08  
GeneralRe: thankes PinmemberGeorge B Gilbert11:23 24 Jun '08  
GeneralThanks!!! PinmemberGlimmerMan4:33 20 Jun '06  
GeneralRe: Thanks!!! PinmemberGeorge B Gilbert5:34 20 Jun '06  
GeneralWell done - how about an enhancement PinmemberBob-ish9:29 2 Mar '06  
GeneralRe: Well done - how about an enhancement PinmemberGeorge B Gilbert11:16 2 Mar '06  
GeneralRe: Well done - how about an enhancement PinmemberBob-ish11:35 2 Mar '06  
GeneralRe: Well done - how about an enhancement Pinmemberjohndsc2:47 27 Oct '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 18 Jan 2006
Editor: Smitha Vijayan
Copyright 2006 by George B Gilbert
Everything else Copyright © CodeProject, 1999-2009
Web22 | Advertise on the Code Project