473,734 Members | 2,764 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

modifying a textbox bound to datasource - rowstate always says UNCHANGED

I have a table with 1 row which is used to hold some application wide items
(one item per field, hence I only need 1 row).

I want to bind one of the fields to a textbox. After setting up the
oledbconnection and dataAdapter and filling the DataSet (ds) I tried this:

TextBox1.DataBi ndings.Add("tex t", ds.Tables.Item( "MyFile"), "MyField")

I then put the following code in the SAVE button click event:

Dim dsChanged As DataSet = ds.GetChanges()
Try *************** ** I put a
breakpoint here and examine ds.tables.item( "MyFile").rows( 0).rowstate
daMyFile.Update (dsChanged.Tabl es("MyFile"))
Catch ex As OleDbException
MsgBox(ex.ToStr ing)
Catch ex As InvalidOperatio nException
MsgBox(ex.ToStr ing)
Catch ex As DBConcurrencyEx ception
MsgBox("concurr ency exception - another user has modified this record" &
vbCr & vbLf & ex.ToString)
ds.RejectChange s()
Exit Sub
End Try
ds.AcceptChange s()

When I run the program I see the proper initial value in the textbox (this
value was obtained from the field MyField in the table MyFile), so I know
the binding is grabing the value from the right place.

However, when I change the value in the textbox and hit the SAVE button, at
the breakpoint I examine the dataset and the rowstate for the row says it is
UNCHANGED. I looked at this because I wondered why my database was not
being updated with the new value. At least I now know why the datatable
didn't change... But can anybody tell me why, when I change the value of
the textbox, the rowstate doesn't reflect the changed status???

I know I must be overlooking something simple, and if anybody can help I
would greatly appreciate it.

Thanks,
John
Nov 21 '05 #1
6 13945
John

One of the most asked questions in these newsgroups.
For databinding there has to be a change of a control others than a button.
Therefore you have to push the data down by hand when you click a button.
(To do it efficient you can do it before the update command)

BindingContext( ds.Tables(0)).E ndCurrentEdit()

I hope this helps,

Cor
Nov 21 '05 #2
Hi Cor,

Again, you have come to my aid! I thank you so much for your
assistance. In an effort to see if I understand exactly what is happening
and to present a fuller picture for those who would benefit from it, let me
try to summerize:

If you bind a textbox to a dataset which has been filled with records from a
table you are dealing with 3 distinct items.

1. the actual textbox.text property, which you can type into
2. the dataset which sits in between the textbox and the datatable on the
disk
3. the actual datatable on the disk.

After typing something into the textbox.text property no changes are made to
either the dataset or datatable.

You can then use the associated bindingcontext to either end the current
edit, like this:

BindingContext( ds.Tables.Item( "MyTable")).End CurrentEdit()

in which case the changes to the textbox.text property is transfered to the
dataset.

Or, you can use the associated bindingcontext to cancel any changes you made
to the textbox.text property, like this:

BindingContext( ds.Tables.Item( "MyTable")).Can celCurrentEdit( )

in which case the changes to the textbox.text property are cancelled and the
dataset remains unchanged.

One of the great things about a dataset is that it automatically keeps the
different "states" of your data. That is, after pushing the textbox changes
to the dataset you can access both the "changed" data or the "original" data
(the dataset keeps both),
by using the "DataRowVersion " specifier when accessing a column in a row...
like this:

ds.Tables.Item( 0).Rows(0)(0, DataRowVersion. Current) --will get the current
value of the field
ds.Tables.Item( 0).Rows(0)(0, DataRowVersion. Original) --will get the
original value of the field

Now we have one more thing to do. We need to push the changed data from the
dataset to the datatable on the disk.
You do this by using the UPDATE method of the DataAdapter (you must have
previously specified the update command for the dataadapter). For efficency
I transfer all changed records to a separate dataset (I call it dsChanged)
and then check to make sure changes exist (ie: is dsChanged nothing?), and
then, if changes exist, use the update method to push the changes back to
the datatable on disk, like this:

Dim dsChanged As DataSet = ds.GetChanges()
If dsChanged Is Nothing Then
MsgBox("no changed records")
Exit Sub
End If
Try
daGeninfo.Updat e(dsChanged.Tab les("MyTable"))
Catch ex As OleDbException
MsgBox(ex.ToStr ing)
Catch ex As InvalidOperatio nException
MsgBox(ex.ToStr ing)
Catch ex As DBConcurrencyEx ception
MsgBox("concurr ency exception - another user has modified this record" &
vbCr & vbLf & ex.ToString)
ds.RejectChange s() 'not really necessary, cause I'm going to clear and
refresh the data, but I wanted to show it
ds.tables.item( "MyFile").c lear 'clear the dataset of old data
da.fill(ds.tabl es.item("MyFile ")) 'refresh it to reflect the new,
updated data
Exit Sub
End Try

One thing deserves explanation, and that is the DBConcurrencyEx ception. If
0 records are updated as a result of the update method then the
DBConcurrencyEx ception event is fired. This doesn't necessarily mean that
there was an actual concurrency violation, it simply means that there were 0
records updated, and that it is MOST LIKELY because of a concurrency
violation. Since you must determine what constitutes a concurrency
violation in your own code (VB does not do it for you.. it can help you by
possibly generating an SQL Update command, but it's still just your code)
you must code your SQL Update command not to update a record if you believe
a concurrency violation has occured.

This is most often done one of two ways, both of which are part of your SQL
Update stmt. The first is to compare every field to it's original value and
only update the record if all the fields on disk match the original values
(stored in the dataset, remember?) like this:

sqlUpdateCmd = "update MyFile set mydatafield=? where mykeyfield= ? and
mydatafield=?"
sqlUpdateCmd.Pa rameters.Add("@ mydatafield", OleDbType.VarCh ar, 13,
"mydatafiel d")
sqlUpdateCmd.Pa rameters.Add("@ mykeyfield", OleDbType.VarCh ar, 13,
"mykeyfield ")
sqlUpdateCmd.Pa rameters.Add("@ mydatafieldorig ", OleDbType.VarCh ar, 13,
"mydatafield"). SourceVersion = DataRowVersion. Original

This is the type of UPDATE command the SQLCommandBuild er or
OledbCommandBui lder class will generate for you, but it can get funky and
doesn't work well all the time.

The second, I believe easier, method is to have a timestamp or counter as
a field in each datatable. Everytime you update a record you update the
timestamp or counter. When specifying the UPDATE command for the
dataadapters update method you include a where clause that compares the
timestamp (or counter) to its original value and only update if they are
equal. The bottom line is that if the values are NOT equal it means that
somebody changed the record while you had it up on your screen, and
therefore, the update command will have updated 0 records (cause it failed
the Where clause test) and it will fire the DBConcurrencyEx ception. At this
point you might want to refresh your data.

I tried to present a full picture of one way to update a datatable, it is
not the only way. The info is accurate to the best of my knowledge and if
anybody has any corrections or additions, feel free to comment (comments
are ALWAYS welcome!).

Hope this helps somebody having trouble figuring it all out...

John


"Cor Ligthert [MVP]" <no************ @planet.nl> wrote in message
news:Og******** *****@TK2MSFTNG P09.phx.gbl...
John

One of the most asked questions in these newsgroups.
For databinding there has to be a change of a control others than a
button.
Therefore you have to push the data down by hand when you click a button.
(To do it efficient you can do it before the update command)

BindingContext( ds.Tables(0)).E ndCurrentEdit()

I hope this helps,

Cor

Nov 21 '05 #3
oops, one more thing I forgot.

after doing the dataAdapter.Upd ate method, if it's successful you might want
to do a:

ds.acceptchange s()

this will reset all the RowState properties for the rows back to "unchanged"

John

"JohnR" <Jo******@hotma il.com> wrote in message
news:eJLIe.18$D 4.1@trndny07...
Hi Cor,

Again, you have come to my aid! I thank you so much for your
assistance. In an effort to see if I understand exactly what is happening
and to present a fuller picture for those who would benefit from it, let
me try to summerize:

If you bind a textbox to a dataset which has been filled with records from
a table you are dealing with 3 distinct items.

1. the actual textbox.text property, which you can type into
2. the dataset which sits in between the textbox and the datatable on the
disk
3. the actual datatable on the disk.

After typing something into the textbox.text property no changes are made
to either the dataset or datatable.

You can then use the associated bindingcontext to either end the current
edit, like this:

BindingContext( ds.Tables.Item( "MyTable")).End CurrentEdit()

in which case the changes to the textbox.text property is transfered to
the dataset.

Or, you can use the associated bindingcontext to cancel any changes you
made to the textbox.text property, like this:

BindingContext( ds.Tables.Item( "MyTable")).Can celCurrentEdit( )

in which case the changes to the textbox.text property are cancelled and
the dataset remains unchanged.

One of the great things about a dataset is that it automatically keeps the
different "states" of your data. That is, after pushing the textbox
changes to the dataset you can access both the "changed" data or the
"original" data (the dataset keeps both),
by using the "DataRowVersion " specifier when accessing a column in a
row... like this:

ds.Tables.Item( 0).Rows(0)(0, DataRowVersion. Current) --will get the
current value of the field
ds.Tables.Item( 0).Rows(0)(0, DataRowVersion. Original) --will get the
original value of the field

Now we have one more thing to do. We need to push the changed data from
the dataset to the datatable on the disk.
You do this by using the UPDATE method of the DataAdapter (you must have
previously specified the update command for the dataadapter). For
efficency I transfer all changed records to a separate dataset (I call it
dsChanged) and then check to make sure changes exist (ie: is dsChanged
nothing?), and then, if changes exist, use the update method to push the
changes back to the datatable on disk, like this:

Dim dsChanged As DataSet = ds.GetChanges()
If dsChanged Is Nothing Then
MsgBox("no changed records")
Exit Sub
End If
Try
daGeninfo.Updat e(dsChanged.Tab les("MyTable"))
Catch ex As OleDbException
MsgBox(ex.ToStr ing)
Catch ex As InvalidOperatio nException
MsgBox(ex.ToStr ing)
Catch ex As DBConcurrencyEx ception
MsgBox("concurr ency exception - another user has modified this record"
& vbCr & vbLf & ex.ToString)
ds.RejectChange s() 'not really necessary, cause I'm going to clear
and refresh the data, but I wanted to show it
ds.tables.item( "MyFile").c lear 'clear the dataset of old data
da.fill(ds.tabl es.item("MyFile ")) 'refresh it to reflect the new,
updated data
Exit Sub
End Try

One thing deserves explanation, and that is the DBConcurrencyEx ception.
If 0 records are updated as a result of the update method then the
DBConcurrencyEx ception event is fired. This doesn't necessarily mean that
there was an actual concurrency violation, it simply means that there were
0 records updated, and that it is MOST LIKELY because of a concurrency
violation. Since you must determine what constitutes a concurrency
violation in your own code (VB does not do it for you.. it can help you
by possibly generating an SQL Update command, but it's still just your
code) you must code your SQL Update command not to update a record if you
believe a concurrency violation has occured.

This is most often done one of two ways, both of which are part of your
SQL Update stmt. The first is to compare every field to it's original
value and only update the record if all the fields on disk match the
original values (stored in the dataset, remember?) like this:

sqlUpdateCmd = "update MyFile set mydatafield=? where mykeyfield= ? and
mydatafield=?"
sqlUpdateCmd.Pa rameters.Add("@ mydatafield", OleDbType.VarCh ar, 13,
"mydatafiel d")
sqlUpdateCmd.Pa rameters.Add("@ mykeyfield", OleDbType.VarCh ar, 13,
"mykeyfield ")
sqlUpdateCmd.Pa rameters.Add("@ mydatafieldorig ", OleDbType.VarCh ar, 13,
"mydatafield"). SourceVersion = DataRowVersion. Original

This is the type of UPDATE command the SQLCommandBuild er or
OledbCommandBui lder class will generate for you, but it can get funky and
doesn't work well all the time.

The second, I believe easier, method is to have a timestamp or counter
as a field in each datatable. Everytime you update a record you update
the timestamp or counter. When specifying the UPDATE command for the
dataadapters update method you include a where clause that compares the
timestamp (or counter) to its original value and only update if they are
equal. The bottom line is that if the values are NOT equal it means that
somebody changed the record while you had it up on your screen, and
therefore, the update command will have updated 0 records (cause it failed
the Where clause test) and it will fire the DBConcurrencyEx ception. At
this point you might want to refresh your data.

I tried to present a full picture of one way to update a datatable, it is
not the only way. The info is accurate to the best of my knowledge and
if anybody has any corrections or additions, feel free to comment
(comments are ALWAYS welcome!).

Hope this helps somebody having trouble figuring it all out...

John


"Cor Ligthert [MVP]" <no************ @planet.nl> wrote in message
news:Og******** *****@TK2MSFTNG P09.phx.gbl...
John

One of the most asked questions in these newsgroups.
For databinding there has to be a change of a control others than a
button.
Therefore you have to push the data down by hand when you click a button.
(To do it efficient you can do it before the update command)

BindingContext( ds.Tables(0)).E ndCurrentEdit()

I hope this helps,

Cor


Nov 21 '05 #4
John,
after doing the dataAdapter.Upd ate method, if it's successful you might
want to do a:

ds.acceptchange s()

This is absolute needed in the way you describe it with the copy of the
dataset that holds the changes (I hope you don't force me to check all your
text, it seems quiet complete).

If the original dataset is updated than this ds.acceptchange s is not needed
because in the update is a step build in that does an acceptchanges in the
supported dataset.

Nice written by the way.

Cor
Nov 21 '05 #5
Thanks for Cor's solution and JohnR's detailed writeup. I was having a
similar problem, and the notes in this thread helped me resolve my issue.
However, I still don't completely understand what is going on as I've noticed
some confusing things.

In particular, before adding the EndCurrentEdit statement, I could see
(through debugger watches) that the dataset fields *were* being updated and I
had both Current and Proposed versions of my record. OTOH, the RowState
property was Unchanged, so there were no database rows updated with my Update
statement. After adding the EndCurrentEdit statement, the RowState would
become Modified and the Update command would change the database.

Incidentally, I did not see an "EndCurrentEdit " statement in the "update"
examples that I've found, including ones in Balena's book and the one on
Visual Studio's page on the DataRowVersion Enumeration. I can see why this is
one of the most asked question in the newsgroup by us newbies. :-)
Nov 21 '05 #6
Hi Timbobd,

I really can't speak for why you see changes in the dataset before doing
a endCurrentEdit, but you should be aware that a number of controls that
modify data will do an implicit 'endCurrentEdit ' when your current row loses
focus, for example. Sometimes you can control when the implicit EndCurrent
Edit occurs, other times you can't. I agree that it is most confusing when
you have a method that sometimes is called 'behind the scenes' and at other
times, you have to call it explicitly. I've discovered most of the cases by
trial and error, and I just see what works.

John

"timbobd" <ti*****@discus sions.microsoft .com> wrote in message
news:A0******** *************** ***********@mic rosoft.com...
Thanks for Cor's solution and JohnR's detailed writeup. I was having a
similar problem, and the notes in this thread helped me resolve my issue.
However, I still don't completely understand what is going on as I've
noticed
some confusing things.

In particular, before adding the EndCurrentEdit statement, I could see
(through debugger watches) that the dataset fields *were* being updated
and I
had both Current and Proposed versions of my record. OTOH, the RowState
property was Unchanged, so there were no database rows updated with my
Update
statement. After adding the EndCurrentEdit statement, the RowState would
become Modified and the Update command would change the database.

Incidentally, I did not see an "EndCurrentEdit " statement in the "update"
examples that I've found, including ones in Balena's book and the one on
Visual Studio's page on the DataRowVersion Enumeration. I can see why this
is
one of the most asked question in the newsgroup by us newbies. :-)

Nov 21 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

13
4331
by: Paul Slavin | last post by:
I have a textbox bound to a dataview, when I update the text in the textbox no changes take place in the underlying dataset. Why is this?? any answers appreciated, as to due to the underlying structure of the datasets, i.e lots of child tables etc, I cannot use bindingcontext
2
3711
by: certolnut | last post by:
Hi all I'm using the "Merge" method for datasets to append data from an external excel spreadsheet into a Sql Server Table The problem is that "Merge" method copies over the current RowState (UNCHANGED)of the excel spreadsheet rows, so when I try to update the data adapter for Sql Server, it won't update the database (The DataAdapter won't process rows that are set as "Unchanged"
2
2172
by: Phil Townsend | last post by:
I have a datagrid in a windows forms application. The datagrid gets its data via a web service. Users can modify rows in the datagrid then post their changes. However, when changes are made the rowstate remains "Added" for all the rows--those that were modified AND those that were unchanged. Here is the code I am using to test (dsitems is the underlying dataset): private void btnSave_Click(object sender, System.EventArgs e) { string...
3
1644
by: matthew schouppe | last post by:
I have a datagrid with two columns, the first a normal bound column, the second is a template column created from a bound column. For the ItemTemplate of the Template Column, I removed the label and replaced it with a textbox. Displaying the data from the datasource is not a problem, however when I change the data in the textbox and click on an update button (the thought being that multiple rows will have been changed and I can simply...
6
11292
by: timbobd | last post by:
I have a Windows form that displays a database table in a DataGrid. When you click on a row, the row's values get copied to bound TextBoxes below, and when the "Save" button is clicked the database is updated (as is the DataGrid row) with changed values in the TextBoxes. Here are some observations: 1) When changes are typed into a text box and "Save" is clicked, the changes are reflected in the DataSet.Tables().Rows().ItemArray value, but...
1
2054
by: AssOnFire | last post by:
Hello, I have bound a textbox to a CustomerName column of my DB, using the data binding property, and selected it from the DataTable. when i change the text in the texbBox, i try to update the DataSource but no luck, it seems that the datarow wasn't affected. Hows the binding of the textBox supposed to make the change in the data row? if not - how to i solve this problem and make every change of the text
5
8016
by: Ken Varn | last post by:
I have just started using VS.NET 2005 after using VS.NET 2003. One of the things that I noticed is that in ASP.NET, the DataSource property for TextBoxes and other web controls is no longer available from 2003 to 2005. Is there some other method available to bind TextBoxes that I am not seeing? I have seen some articles on the web stating that you can only bind to grid and list controls. Seems like a step backward to me. Why would the...
4
1700
by: sklett | last post by:
(I posted this in a databinding NG, but it's a VERY low traffic NG so I thought I would post here as well. I hope no one minds too much, if you do I'm sorry) I have a DGV that is bound to a DataTable that is loaded during application startup. I can sort with all the columns and everything works fine. I have a method that can be invoked from a context menu that will loop through the rows of the bound table and modify a specific cell in...
12
13642
by: cj | last post by:
When viewing a datatable in a datagridview one of the columns in it is a "note" field which can be quite long. I would like to have the note field of the currently selected row of the datagrid display in a textbox below the datgridview. I currently have it fixed so if you click on a row the note field from that row is put in the textbox. I'd like this to be automatic as they move through rows. Also the note field is one of two fields...
0
8946
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9449
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9236
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8186
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6735
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4550
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3261
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2724
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2180
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.