Flaw in DataGrid Handling of New Records

  • Thread starter Thread starter Mark Olbert
  • Start date Start date
M

Mark Olbert

I believe there is a flaw in the way the Windows.Forms.DataGrid handles the creation of new
rows/records.

The observations in this post are based on a DataGrid bound to a DataRelation (specifically, the
child side of the DataRelation). The DataGrid is a control on a data form which displays one record
at a time. All the tables involved use autosequence fields with a starting value of -1 and an
increment of -1 (so newly created record IDs won't interfere with the existing records in the
underlying SQL Server tables).

When a user clicks on a cell in the "add new" row of a DataGrid, the row gets populated with default
values for the fields being displayed, and the foreign key field in the child table gets set to the
current master table autosequence id number. However, the "row" does not yet exist in the underlying
DataSource for the DataGrid. In fact, so far as I can tell, the row only gets created in the
underlying DataSource when you move off the current master record.

In and of itself this wouldn't be a problem, but because the "row" doesn't exist in the underlying
DataSource, any SqlAdapter.Update() operation won't involve it. This also appears to lead to some
odd "null object" errors inside the SqlAdapter.Update() method call.

Moreover, if the master record itself is a newly-created record, a call to SqlAdapter.Update() will
force the user to encounter an error when he/she moves off the master record. This error occurs
because the SqlAdapter.Update() adds the new master record to the underlying Sql Server table and
"assigns" a valid autosequence id number to the master record...which has to be different from the
master id number appearing as a foreign key in the DataGrid, and, since the DataGrid "row" doesn't
yet exist in any DataTable, the change in master record id number doesn't propagate to the new
"row". .NET flags this inconsistency when the user attempts to move off the master record. Needless
to say, this is quite confusing to the user.

So far the only workaround I've found for this flaw is to block any attempt to call
SqlAdapter.Update() when any DataGrid is in this "new record in limbo" state. Personally, I think
that's a real ugly solution (made even worse because the only algorithm I could find on the web for
determining if a DataGrid has one of these "new but not yet stored" rows is to compare the number of
rows in the DataGrid's BindingManagerBase to the number of rows the master record "thinks" exist via
a call to GetChildRows()).

What confuses me is that it appears ADO.NET has an architecture that would allow the creation of
"pending" DataRows in the underlying DataTable, which could then be either canceled away or not
depending upon what the user did to the DataGrid. In fact, I suspect I could add this capability
myself by forcing the user to click an "Add New Detail Record" button and wrapping the creation of a
new DataGrid row with BeginEdit(), EndEdit() and CancelEdit() calls. But that's not as transparent a
user interface as just letting the user click in the "add a new row" row of a DataGrid and start
typing.

I'd be interested in hearing any thoughts or other solutions people have on this issue.

- Mark
 
Hi Mark,
I apologize for the delay. I did replied your post yesterday, however
for unknown reason the server failed to update it to newsgroup.
Now I repost it below.

Hi Mark,
I'm researching on this issue, but it's not quite clear about your
problem. I've made a test c# windows application. added a datagrid and a
master-detail relation(Northwind, "Categories" and "Products").but thing's
are not clear that how to get the error you mentioned?
I'll be appreciate if you could provide a simple sample project to repro
this problem, I believe this will help a lot, thanks!

Best regards,

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
You should not reply this mail directly, "Online" should be removed before
sending, Thanks!

--------------------
| X-Tomcat-ID: 200414101
| References: <[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain
| Content-Transfer-Encoding: 7bit
| From: (e-mail address removed) (Ying-Shen Yu[MSFT])
| Organization: Microsoft
| Date: Tue, 23 Sep 2003 08:28:19 GMT
| Subject: RE: Flaw in DataGrid Handling of New Records
| X-Tomcat-NG: microsoft.public.dotnet.framework.windowsforms
| Message-ID: <[email protected]>
| Newsgroups: microsoft.public.dotnet.framework.windowsforms
| Lines: 142
| Path: cpmsftngxa06.phx.gbl
| Xref: cpmsftngxa06.phx.gbl
microsoft.public.dotnet.framework.windowsforms:52921
| NNTP-Posting-Host: TOMCATIMPORT1 10.201.218.122
|
| Hi Mark,
| I'm researching on this issue, but it's not quite clear about your
| problem. I've made a test c# windows application. added a datagrid and a
| master-detail relation(Northwind, "Categories" and "Products").but
thing's
| are not clear that how to get the error you mentioned?
| I'll be appreciate if you could provide a simple sample project to repro
| this problem, I believe this will help a lot, thanks!
|
|
| Best regards,
|
| Ying-Shen Yu [MSFT]
| Microsoft Online Partner Support
| Get Secure! - www.microsoft.com/security
|
| This posting is provided "AS IS" with no warranties and confers no rights.
| You should not reply this mail directly, "Online" shouldbe removed before
| sending, Thanks!
|
| --------------------
| | NNTP-Posting-Date: Mon, 22 Sep 2003 21:39:28 -0500
| | From: Mark Olbert <[email protected]>
| | Newsgroups: microsoft.public.dotnet.framework.windowsforms
| | Subject: Flaw in DataGrid Handling of New Records
| | Date: Mon, 22 Sep 2003 19:39:27 -0700
| | Organization: Olbert & McHugh, Ltd.
| | Reply-To: (e-mail address removed)
| | Message-ID: <[email protected]>
| | X-Newsreader: Forte Agent 1.93/32.576 English (American)
| | MIME-Version: 1.0
| | Content-Type: text/plain; charset=us-ascii
| | Content-Transfer-Encoding: 7bit
| | Lines: 46
| | X-Trace:
|
sv3-MzT2cutfyGTVkELulhwXFZdBRamEky4NS9Sind6HR6O+n9QbeZAadhFoleH8nd2yH7m7g0kf
|
N7n9f2s!t+nL8BliR3S32OFgV1AhzTzYop/oHFjM0c8Akzb8Q1bGlqAnKdr1eVtaYmc/X++ccC++
| uw==
| | X-Complaints-To: (e-mail address removed)
| | X-DMCA-Notifications: http://www.giganews.com/info/dmca.html
| | X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
| | X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your
| complaint properly
| | X-Postfilter: 1.1
| | Path:
|
cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!newsfeed00.sul.t-online.de!t-onlin
|
e.de!news-lei1.dfn.de!news-fra1.dfn.de!npeer.de.kpn-eurorings.net!news2.tele
|
byte.nl!logbridge.uoregon.edu!newshub.sdsu.edu!small1.nntp.aus1.giganews.com
|
!border1.nntp.aus1.giganews.com!intern1.nntp.aus1.giganews.com!nntp.giganews
| .com!news.giganews.com.POSTED!not-for-mail
| | Xref: cpmsftngxa06.phx.gbl
| microsoft.public.dotnet.framework.windowsforms:52911
| | X-Tomcat-NG: microsoft.public.dotnet.framework.windowsforms
| |
| | I believe there is a flaw in the way the Windows.Forms.DataGrid handles
| the creation of new
| | rows/records.
| |
| | The observations in this post are based on a DataGrid bound to a
| DataRelation (specifically, the
| | child side of the DataRelation). The DataGrid is a control on a data
form
| which displays one record
| | at a time. All the tables involved use autosequence fields with a
| starting value of -1 and an
| | increment of -1 (so newly created record IDs won't interfere with the
| existing records in the
| | underlying SQL Server tables).
| |
| | When a user clicks on a cell in the "add new" row of a DataGrid, the
row
| gets populated with default
| | values for the fields being displayed, and the foreign key field in the
| child table gets set to the
| | current master table autosequence id number. However, the "row" does
not
| yet exist in the underlying
| | DataSource for the DataGrid. In fact, so far as I can tell, the row
only
| gets created in the
| | underlying DataSource when you move off the current master record.
| |
| | In and of itself this wouldn't be a problem, but because the "row"
| doesn't exist in the underlying
| | DataSource, any SqlAdapter.Update() operation won't involve it. This
also
| appears to lead to some
| | odd "null object" errors inside the SqlAdapter.Update() method call.
| |
| | Moreover, if the master record itself is a newly-created record, a call
| to SqlAdapter.Update() will
| | force the user to encounter an error when he/she moves off the master
| record. This error occurs
| | because the SqlAdapter.Update() adds the new master record to the
| underlying Sql Server table and
| | "assigns" a valid autosequence id number to the master record...which
has
| to be different from the
| | master id number appearing as a foreign key in the DataGrid, and, since
| the DataGrid "row" doesn't
| | yet exist in any DataTable, the change in master record id number
doesn't
| propagate to the new
| | "row". .NET flags this inconsistency when the user attempts to move off
| the master record. Needless
| | to say, this is quite confusing to the user.
| |
| | So far the only workaround I've found for this flaw is to block any
| attempt to call
| | SqlAdapter.Update() when any DataGrid is in this "new record in limbo"
| state. Personally, I think
| | that's a real ugly solution (made even worse because the only algorithm
I
| could find on the web for
| | determining if a DataGrid has one of these "new but not yet stored"
rows
| is to compare the number of
| | rows in the DataGrid's BindingManagerBase to the number of rows the
| master record "thinks" exist via
| | a call to GetChildRows()).
| |
| | What confuses me is that it appears ADO.NET has an architecture that
| would allow the creation of
| | "pending" DataRows in the underlying DataTable, which could then be
| either canceled away or not
| | depending upon what the user did to the DataGrid. In fact, I suspect I
| could add this capability
| | myself by forcing the user to click an "Add New Detail Record" button
and
| wrapping the creation of a
| | new DataGrid row with BeginEdit(), EndEdit() and CancelEdit() calls.
But
| that's not as transparent a
| | user interface as just letting the user click in the "add a new row"
row
| of a DataGrid and start
| | typing.
| |
| | I'd be interested in hearing any thoughts or other solutions people
have
| on this issue.
| |
| | - Mark
| |
|
|
 
Ying-Shen,

I will try to create a cutdown project that illustrates the problem, but I won't be able to get to
it for several days.

- Mark
 
Hi Mark,

call EndCurrentUpdates() on the underlying data table before you call the dataAdapter.Update().
This will make a "nonpermanent row" permanent, pending changes will be written to the data source. This also helps with textboxes
that
do not get their changes saved if they don't loose focus.

I'm not shure if it is a solution in your context, but I'd like to hear if it did.
HTH, Ulrich

Mark Olbert said:
I believe there is a flaw in the way the Windows.Forms.DataGrid handles the creation of new
rows/records.
....
 
Hi Mark,
Thanks for your sample project, I've successfully reproduced your problem.

The cause of the problem is the values in the current editing row doen't
get updated when the underlying data source is being updated. Then the
auto-generated foreign key doesn't match
the key in parent table then the error message shown up. It maybe a
limitation. I'll report it to our product team.

I think you may try handling the ColumnChanged event of the master table,
and then update the foreign key cell in current editing row manually.

If you have anything unclear or have trouble in implementing, please be
free to let me know.
Thanks!


Best regards,

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
You should not reply this mail directly, "Online" should be removed before
sending, Thanks!

--------------------
| NNTP-Posting-Date: Mon, 22 Sep 2003 21:39:28 -0500
| From: Mark Olbert <[email protected]>
| Newsgroups: microsoft.public.dotnet.framework.windowsforms
| Subject: Flaw in DataGrid Handling of New Records
| Date: Mon, 22 Sep 2003 19:39:27 -0700
| Organization: Olbert & McHugh, Ltd.
| Reply-To: (e-mail address removed)
| Message-ID: <[email protected]>
| X-Newsreader: Forte Agent 1.93/32.576 English (American)
| MIME-Version: 1.0
| Content-Type: text/plain; charset=us-ascii
| Content-Transfer-Encoding: 7bit
| Lines: 46
| X-Trace:
sv3-MzT2cutfyGTVkELulhwXFZdBRamEky4NS9Sind6HR6O+n9QbeZAadhFoleH8nd2yH7m7g0kf
N7n9f2s!t+nL8BliR3S32OFgV1AhzTzYop/oHFjM0c8Akzb8Q1bGlqAnKdr1eVtaYmc/X++ccC++
uw==
| X-Complaints-To: (e-mail address removed)
| X-DMCA-Notifications: http://www.giganews.com/info/dmca.html
| X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
| X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your
complaint properly
| X-Postfilter: 1.1
| Path:
cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!newsfeed00.sul.t-online.de!t-onlin
e.de!news-lei1.dfn.de!news-fra1.dfn.de!npeer.de.kpn-eurorings.net!news2.tele
byte.nl!logbridge.uoregon.edu!newshub.sdsu.edu!small1.nntp.aus1.giganews.com
!border1.nntp.aus1.giganews.com!intern1.nntp.aus1.giganews.com!nntp.giganews
com!news.giganews.com.POSTED!not-for-mail
| Xref: cpmsftngxa06.phx.gbl
microsoft.public.dotnet.framework.windowsforms:52911
| X-Tomcat-NG: microsoft.public.dotnet.framework.windowsforms
|
| I believe there is a flaw in the way the Windows.Forms.DataGrid handles
the creation of new
| rows/records.
|
| The observations in this post are based on a DataGrid bound to a
DataRelation (specifically, the
| child side of the DataRelation). The DataGrid is a control on a data form
which displays one record
| at a time. All the tables involved use autosequence fields with a
starting value of -1 and an
| increment of -1 (so newly created record IDs won't interfere with the
existing records in the
| underlying SQL Server tables).
|
| When a user clicks on a cell in the "add new" row of a DataGrid, the row
gets populated with default
| values for the fields being displayed, and the foreign key field in the
child table gets set to the
| current master table autosequence id number. However, the "row" does not
yet exist in the underlying
| DataSource for the DataGrid. In fact, so far as I can tell, the row only
gets created in the
| underlying DataSource when you move off the current master record.
|
| In and of itself this wouldn't be a problem, but because the "row"
doesn't exist in the underlying
| DataSource, any SqlAdapter.Update() operation won't involve it. This also
appears to lead to some
| odd "null object" errors inside the SqlAdapter.Update() method call.
|
| Moreover, if the master record itself is a newly-created record, a call
to SqlAdapter.Update() will
| force the user to encounter an error when he/she moves off the master
record. This error occurs
| because the SqlAdapter.Update() adds the new master record to the
underlying Sql Server table and
| "assigns" a valid autosequence id number to the master record...which has
to be different from the
| master id number appearing as a foreign key in the DataGrid, and, since
the DataGrid "row" doesn't
| yet exist in any DataTable, the change in master record id number doesn't
propagate to the new
| "row". .NET flags this inconsistency when the user attempts to move off
the master record. Needless
| to say, this is quite confusing to the user.
|
| So far the only workaround I've found for this flaw is to block any
attempt to call
| SqlAdapter.Update() when any DataGrid is in this "new record in limbo"
state. Personally, I think
| that's a real ugly solution (made even worse because the only algorithm I
could find on the web for
| determining if a DataGrid has one of these "new but not yet stored" rows
is to compare the number of
| rows in the DataGrid's BindingManagerBase to the number of rows the
master record "thinks" exist via
| a call to GetChildRows()).
|
| What confuses me is that it appears ADO.NET has an architecture that
would allow the creation of
| "pending" DataRows in the underlying DataTable, which could then be
either canceled away or not
| depending upon what the user did to the DataGrid. In fact, I suspect I
could add this capability
| myself by forcing the user to click an "Add New Detail Record" button and
wrapping the creation of a
| new DataGrid row with BeginEdit(), EndEdit() and CancelEdit() calls. But
that's not as transparent a
| user interface as just letting the user click in the "add a new row" row
of a DataGrid and start
| typing.
|
| I'd be interested in hearing any thoughts or other solutions people have
on this issue.
|
| - Mark
|
 
Back
Top