Click here to Skip to main content
15,868,016 members
Please Sign up or sign in to vote.
2.50/5 (2 votes)
See more:
I have a simple data form that has various controls on it bound to data in a sql server database using all the visual tools such as dataset, tableadapters, and binding source.

Example firstname textbox, lastname textbox, date textbox (though on my form there are many more)

I need to determine if any data in any of those controls was modified so I can ask the user if they want to save before continuing, and enable the save button, things like that.

I can use the various events for each control such as validated, but I would have to do that for each control on the form, and it seems that would be something simpiler in say the binding source.

However, the bindingsource.currentchanged event fires whether or not anything was modified, and I have tried everything else I can think of.

I am thinking it shouldn't be that complicated.

Thanks in advance,
Posted
Comments
Sergey Alexandrovich Kryukov 21-Sep-12 13:07pm    
To start with, you need to write down exact class name of the class you are working about. Fully-qualified, with its namespace, because many different classes in different libraries have the same simple name. Please use "Improve question" above.
--SA

Well, since you're working with a DataSet [^]it seems safe to assume you are actually binding to this and display a DataRow [^]on screen.
You could loop through the DataRows [^]in your DataSet and look at the RowState Property[^]. This returns a DataRowState Enumeration[^] value.
I think it's pretty obvious from there. Hope it helps :)

P.S. You're asking for an Event that triggers when anything changes. Obviously, when you use this method you don't need an Event anymore!
 
Share this answer
 
v3
Comments
Joe Fager 21-Sep-12 14:07pm    
Yes, I understand this solution. However, I don't know when to check the RowState Property.

I want to check this before the user leaves the form or moves to another record. That way I can ask if they would like to save changes on that record before proceeding. So it would need to be an event such as BindingSource.CurrentChanged the problem with that is it happens after the user navigates to another row.
Sander Rossel 21-Sep-12 18:53pm    
How about when the user clicks the 'Next' or 'Close' button (or FormClosing Event of the Form)? :)
Simply loop through the Rows of the DataTable until a DataRow.RowState returns anything else than Unchanged.
Joe Fager 22-Sep-12 1:27am    
That is probably what I will do. That makes it real easy because all I have to do is check the dataset for changes. dataset.haschanges and handle it from there. I made it a lot harder than it needed to be. I will be wanting to validate the controls individually anyway. As soon as the first validation event fires and passes I can enable the save button, and if they leave the form or the record, I can ask them to save changes.
Sander Rossel 22-Sep-12 3:47am    
Actually I would not use the Validated Event at all. The only thing it allows you to do is trap the user in a Control (e.Cancel), it's the most annoying and user UNfriendly thing I've ever seen and used. Better is to look at the ErrorProvider Component (http://msdn.microsoft.com/en-us/library/system.windows.forms.errorprovider.aspx) and the IDataErrorInfo Interface (http://msdn.microsoft.com/en-us/library/system.componentmodel.idataerrorinfo.aspx). You can neatly do your validations in your business layer (where I think they belong) and clearly, but non-intrusively, show any errors to your users (without trapping them in a Control).
Hi Friend,
I believe that you can use the method that I am gonna provide you here in VB too, since I am not working with VB and this one is in C#, so pretty off the language of your interest but perfect in the way what you require to do. I hope you will be able to translate it in VB since .NET is quite Language independent :-)

Let us look at my solution, that I am giving you here after 1 hr of mind boggling work (only for you my friend)

See, the codes first, then I will explain it below :
The first thing is to define a global boolean
C#
bool changed = false;


The next step is to define this inside Form Load Event:
C#
foreach (Control mycon in this.Controls.OfType<TextBox>())
{
   mycon.TextChanged   +=  new EventHandler(mycon_TextChanged);
}


As you can see here, I simply looped through all the textbox controls (well you can do for other controls also) and added a single event handler function to all of them. Now let us see what's inside this function. so here's the code :

C#
public void mycon_TextChanged(object sender, EventArgs e)
{
    changed = true;
    foreach(Control mycon in this.Controls.OfType<TextBox>())
    {
        mycon.TextChanged -= mycon_TextChanged;
    }
}

Now here I simply set that boolean to true and after that I removed all the event handlers since I guess they are no longer required as the close button now for sure will have to ask for saving the changes (Change has been made).

Now You simply need to test this boolean, and if it is set, implement your codes to save this new data :-) Cheers

Regards
Tushar Srivastava :-)
 
Share this answer
 
v4
Comments
Joe Fager 21-Sep-12 17:32pm    
Thank you very much... I do think that this will work. I can't test it right now, but will not let your work go to waste. I will test it later. Thank you kindly. It makes sense to me and I can already see how it would work in VB.
Er. Tushar Srivastava 21-Sep-12 17:37pm    
Thank you sir, that you found it useful :-)
Sander Rossel 21-Sep-12 18:51pm    
There's a few issues with this approach. First, it only works on TextBoxes, while I'm sure there might be some ComboBoxes, CheckBoxes, RadioButtons, etc. on an average form. Second, it won't work for Controls in any ContainerControls such as Panels, GroupBoxes, TabControls and SplitContainers. The latter is easily fixed by making your method a recursive one. The first isn't so easily fixed. You could use something like the Validated Event for each Control.

The following code fixes these issues (untested):

Private Sub AddValidatedHandlers(Byval c As Control)
If c IsNot Nothing Then
For Each ctrl As Control In c.Controls
AddValidatedHandlers(ctrl)
Next
AddHandler c.Validated, AddressOf Control_Validated
' Alternatively: AddHandler c.Validated, Sub (sender, e) changed = True
End If
End Sub

Now simply call the function as follows:

AddValidatedHandlers(Me)

My biggest problem with this approach, however, is that the moment values are changed 'in the background', or through some other means (for example a pop-up form) your logic is flawed. Only one Object knows if it has been changed or not, and that is the Object you're binding to. In this case the DataRow (which conveniently already tracks if it has been changed for you!). I really suggest you handle logic such as this in the 'business layer' rather than your UI layer.

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900