|
Why Your DataGrid's Updates Don't Show Up
| To follow along with the book, refer to: Chapter 9, Editing the DataGrid Web Control |
When developers first start working with the DataGrid's built-in editing capabilities, one of the most frequent problems that arise
is as follows:
- The developer completes the code/Web control markup for the editable DataGrid and begins testing a DataGrid.
- The developer clicks on a particular row's Edit hyperlink, and the row becomes editable... so far so good.
- After entering values into the various textboxes, the developer clicks the Update button, causing a postback.
- The DataGrid returns to its pre-editing state, but the edited row's old values are displayed!
If this has happened to you, you likely are saying, "What in the world is going on?"
One cause might be that you've forgotten to add the code necessary in the DataGrid's UpdateCommand event handler
to update the database data. More commonly, the cause is one that's a lot less obvious, and therefore harder to catch.
Over at the DataGridGirl.com
FAQ, the DataGridGirl provides an answer and explanation for this common problem:
Question: When I try to do an Update from my Datagrid, I keep getting the old/original values. Why?
Answer: This is caused by calling DataBind() on the grid before
retrieving the updated values. The DataBind() overwrites the updates with the
original values. Usually caused by having the initial DataBind() of the grid
called on every Page_Load.
Solution: call DataBind() only the first time the
page is loaded:
|
Sub Page_Load(s As Object, e As EventArgs)
If Not IsPostBack Then BindGrid()
End Sub
| | VB.NET |
The BindData() Function |
Here, the BindData() is some subroutine that actually performs the databinding on the DataGrid.
|
While the DataGridGirl's answer and explanation is most definitely correct, I wanted to take a moment to provide a bit deeper
explanation. First, realize that whenever an ASP.NET Web page is visited, the Load event of the Page
class fires, and the Page_Load event handler, if provided, executes. Furthermore, this event fires before
events associated with Web controls within the ASP.NET Web page.
For example, when creating an editable DataGrid, we use an EditCommandColumn, which displays the Edit, Update, and Cancel hyperlinks.
When the Edit hyperlink is clicked, the ASP.NET Web page is posted back and the DataGrid's EditCommand event fires,
and the event handler we supplied for this event then runs. However, before the EditCommand event fires, the
Page's Load event fires. To illustrate this, check out the following live demo.
Specifically, in the live demo scroll down to the Trace Information section. There you
can see a message when an event fires. Next, click on one of the DataGrid's Edit hyperlinks. Then, scroll down to the Trace Information
section again - you can see that the DataGrid's EditCommand event fires after the Page's Load
event. (The screenshot on the right is a screenshot of the Trace Information section from this live demo.)
Now, imagine that your Page_Load event handler has code similar to the following:
|
Sub Page_Load(sender as Object, e as EventArgs)
myDataGrid.DataSource = someDataSource
myDataGrid.DataBind()
End Sub
| | VB.NET |
The problem with this code, with respect to editing a DataGrid, is that when a user enters information into the editable row and
clicks the Update hyperlink, the Page_Load event handler will execute prior to the DataGrid's UpdateCommand
event handler. This means that the original values from the database (the ones the user was editing) will be bound to the DataGrid
in the Page_Load event handler. After the Page_Load event handler executes, the DataGrid's
UpdateCommand event handler will then execute. Now, since the DataGrid has been populated with the original
values, the UpdateCommand event handler will read these original values and update the database with the original
values. Hence, the user's edited values are not saved to the database, and that's why the DataGrid does not appear updated - because
the database was not updated because the user's edited values were "overwritten" by the Page_Load event handler before
the UpdateCommand event handler got a chance to run.
The solution to this is to only rebind the DataGrid in the Page_Load event handler when there is not a postback. We
can check if the page has been posted back via the Boolean Page.IsPostBack property. Since we only want to bind the
data to the DataGrid in the Page_Load event handler when the page is not being posted back, we simply need to
use the following code in our Page_Load event handler:
|
Sub Page_Load(sender as Object, e as EventArgs)
If Not Page.IsPostBack then
myDataGrid.DataSource = someDataSource
myDataGrid.DataBind()
End If
End Sub
| | VB.NET |
|