Link to home
Start Free TrialLog in
Avatar of fruhj
fruhj

asked on

vb.net 2.0 winforms - how to detect unsaved data in databound fields?

I have a form in a winforms app.

It's a data entry form with a bunch of fields (no gridview)

Is there a way to either autosave, or detect if data has changed on the form, so that when the user closes the form, they can get an alert asking them to save the data if they haven't already done so?

Thanks!

- Jack
Avatar of Brian Crowe
Brian Crowe
Flag of United States of America image

the typical way is to have a boolean variable that is set whenever any of your bound controls are changed.  Otherwise you can check the rowstate of the current row of the bindingmanager.
Avatar of Sancler
Sancler

Two points

1)  For changes made by a user in databound controls to get committed to the datatable the "current edit" has to be "ended".  Sometimes this happens automatically (particularly if the user navigates to a new row) but sometimes - quite possibly if a user moves directly from editing in a bound control to closing a form - it is necessary to do it expressly by calling the relevant binding manager's (probably a CurrencyManager's) .EndCurrentEdit method or the BindingSource's .EndEdit.

2)  Once user-made changes have been committed to the datatable, the .RowStates of the rows concerned are set to indicate that.  The .HasChanges property of a dataset will indicate if there are unsaved changes.  This is explained in the "How to: Check for Changed Rows" heading of the Help File.

So you need to put code in a suitable event sub - Closing, probably - to .EndCurrentEdit or .EndEdit and to check .HasChanges.

Roger
Autosave is easy.  Just run your save code from the form's Closing event.

To detect changes, I would run a recursive subroutine that will automatically add a handler to the value or text changed events of each control.  The handler would then enable or disable the Save button depending upon the existance of changes.  You could then check the status of the Save button in the Form's Closing event.
Avatar of fruhj

ASKER

Thanks guys,

I'm with you on the save command embeded in the form close event.
What I was looking to do was present a messagebox first - a "do you want to save?" message with a yes/no
I've got that working so far so good.

What I was hopeing was that there was an easy way to track changes to data bound controls on a form, so I don't ask the user if they want to save, if nothing has actually been edited.

Roberts idea makes sense for doing this manually.

Does any one know if there is a built in or automatic way of doing this in .net 2.0?  I assume the existing code, as generated by microsoft, already tracks changes for the purpose of writing the changes to disk when the save icon is clicked - I'm assuming they don't write every record back, only the changed ones - if so, how do I tap into that awareness mechanism for use in my form closing procedure?
Sancler's method would be the closest way to do this automatically, but in .net 1.1 I found that not all controls responded to the CurrencyManager's EndCurrentEdit command.

Note: The dataset always tracks changes (2.0 and 1.x).  It is stored at the row level.  Each datarow has a rowstate that the data adapter uses to determine which rows to write to the server.  This way you can safely do an Adapter.Update at any time and only the changed rows will update.
You may also be interested in my tutorial on Databinding and Adapters in VS2003.
http://vsnetdatabinding.blogspot.com/
Avatar of fruhj

ASKER

Cool tutorial - think you'll do a VS 2005 version.

Have you tried camtasia? nice little screen recorder app - takes a lot of the pain out of making tutorials.

- Jack
ASKER CERTIFIED SOLUTION
Avatar of RobertRFreeman
RobertRFreeman
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I use Gadwin PrintScreen, which also does a good job.
Avatar of fruhj

ASKER

Cool, I really like that codeproject site.

I'll have to check out gadwin - for still grabs, I use alt-printscreen or paintshop pro - both have their downfalls.

Camtasia captures motion and is great for explaining things like what happens from record to record, moving through a list etc...
I also have used a free program called wink, and then theres' always the windows media encoder which is also free

Camtasia:
   $300
   include sound, video - easily
   Export to common formats like flash

Wink:
   $Free
   no sound support
   export to common formats like flash

Windows media encoder:
   $Free download off MS website
   Includes sound support
   records screen and saves as windows media fomat only - no flash.

I'll check out your 4 articles on codeproject - I'm looking forward to reading them!
   
Avatar of fruhj

ASKER

Hey just some quick follow up here.

Sanclers first post was dead on for what I was trying to do on a page with a grid view.
I was about to award points, and I realized I had asked this question for a form without a grid (another project I am working on)

I want to be sure that I am being fair to the experts for answering the question asked.

- Jack
Both methods should work with the grid as well.
I agree with Robert.  With a datagridview .EndCurrentEdit may be less necessary, just because the user is more likely to have navigated to another row so that it will have happened automatically.  But it does no harm in that case and it may genuinely be needed in the other case.

Roger
Avatar of fruhj

ASKER

Sanclare, your code suggestions were perfect.

For the record, heres what I did and where (so far this is on a datagrid):

Private Sub form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        Dim response As MsgBoxResult
        If RegistrationSystemDataSet.HasChanges = True Then
            response = MsgBox("You have unsaved changes. Save them now?", MsgBoxStyle.YesNoCancel + MsgBoxStyle.Question, "Exiting - Save Changes?")
            If response = MsgBoxResult.Yes Then
                'save (and exit)
                Me.Validate()
                Me.UsersBindingSource.EndEdit()
                Me.UsersTableAdapter.Update(Me.RegistrationSystemDataSet.users)
            ElseIf response = MsgBoxResult.Cancel Then
                'cancel will keep the form open so they can continue
                e.Cancel = True
            End If
        End If
    End Sub

I copied the system generated code from the save button to the above, which is where I got the endedit  and update statements that were also suggested by Sancler - the key I was missing was what to check for - the line  If RegistrationSystemDataSet.HasChanges = True  was what I was after and it works great!


SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial