DataGrid Edit Problem

R

rn5a

A Form has a DataGrid which displays records from a SQL Server 2005 DB
table. Users can modify the records using this DataGrid for which I am
using EditCommandColumn in the DataGrid. This is the code:

<script runat="server">
Dim sqlConn As New SqlConnection(".....")

Sub Page_Load(ByVal obj As Object, ByVal ea As EventArgs)
If Not (Page.IsPostBack) Then
FillDataGrid()
End If
End Sub

Sub EditData(ByVal obj As Object, ByVal ea As
DataGridCommandEventArgs)
FillDataGrid(ea.Item.ItemIndex)
End

Sub FillDataGrid(Optional ByVal EditIndex As Integer = -1)
Dim dSet As DataSet
Dim sqlDapter As SqlDataAdapter

sqlDapter = New SqlDataAdapter("SELECT * FROM Users", sqlConn)
Response.Write("EditIndex: " & EditIndex & "<br>")

dSet = New DataSet
sqlDapter.Fill(dSet)

dgUsers.DataSource = dSet
dgUsers.DataBind()
End Sub
</script>

<form runat="server">
<asp:DataGrid ID="dgUsers" OnEditCommand="EditData" runat="server">
<Columns>
<asp:TemplateColumn HeaderText="UserName">
<ItemTemplate>
<asp:Label ID="lblUserName" runat="server"><%#
Container.DataItem("UserName") %></asp:Label>
</ItemTemplate>
</asp:TemplateColumn>

<asp:BoundColumn DataField="FirstName" HeaderText="First Name"/>
<asp:BoundColumn DataField="LastName" HeaderText="Last Name"/>
<asp:BoundColumn DataField="Address" HeaderText="Address"/>

<asp:EditCommandColumn CancelText="CANCEL" EditText="EDIT"
HeaderText="Edit" UpdateText="UPDATE"/>

<asp:ButtonColumn CommandName="Delete" HeaderText="Delete"
Text="DELETE"/>
</Columns>
</asp:DataGrid>
</form>

Now when the page loads for the first time, as expected, the DataGrid
displays all the records with each row accompanied by the "Edit" link.
But when the "Edit" link of any of the rows is clicked, the
BoundColumns (i.e. FirstName, LastName & Address) do not change to
TextBoxes.

What am I doing wrong here?
 
G

Gozirra

You must set the EditItemIndex of the grid.

In the edit command add this line before binding the grid.
dgUsers.EditItemIndex = ea.Item.ItemIndex

You could also add the line above to the FillDataGrid sub prior to the
databind as well.

Hope this helps.
 
R

rn5a

Yeah...you are correct, Gozirra....I was missing the
dgUser.EditItemIndex = ea.Item.ItemIndex line.

Another problem I am facing is in the UpdateCommand event handler of
the DataGrid. When a row in the DataGrid is in the editable mode, the
second, third & fourth cells of that row i.e. FirstName, LastName &
Address will get replaced by TextBoxes. The current row in editable
mode will also display the "Update" & "Cancel" links. This is the code
in the UpdateCommand event handler of the DataGrid:

Sub UpdateUsers(ByVal obj As Object, ByVal ea As
DataGridCommandEventArgs)
'this code only show the code for the
'Address TextBox which is the 4th cell

Dim strAddress As String
Dim txtAddress As TextBox

txtAddress = CType(ea.Item.Cells(3).Controls(0), TextBox)
strAddress = txtAddress.Text

Response.Write(strAddress)

dgUsers.EditItemIndex = -1
dgUsers.DataBind()
End Sub

Now assume that the Text in the Address TextBox when the DataGrid is in
the editable mode is "House No. 45, Park Avenue Road". I change it to
"Room No. 65, Marine Lines" & then click the "Update" link. When the
page posts back, the Response.Write(strAddress) still displays the old
address i.e. "House No. 45, Park Avenue Road" & not the updated address
"Room No. 65, Marine Lines".

How do I retrieve the updated address after clicking the "Update" link?
 
R

rn5a

Gozirra, I resolved the problem finally. The updated values were not
reflected because the Page_Load sub was calling dgUsers.DataBind after
every post back. Actually I came across a post which helped me resolve
the issue.

The post said that "If you are re-binding data on Page Load, the
control values would get reset to the original values". I couldn't
exactly understand why do the TextBox values get reset to the original
values if dgUsers.DataBind is called after every post back.

Could you please throw some light on why does this happen?
 
G

Gozirra

I'm glad. I created a small test and everything was working fine. I
was getting ready to ask you if you were rebinding somewhere before the
update event.

It all has to do with the page lifecycle. The Page_Load event fires
after the viewstate is loaded but before the update event. When the
grid is rebound to the data, the viewstate values are overwritten and
the edited data is lost (edited data comes from ViewState). So when
the update event is fired later in the cycle, it reads the data and as
you found out, you are left looking at the same values prior to the
edit.

This link in MSDN will show you the order in which events are fired.
Its actually for Mobile web forms but it holds true for standard pages
as well.

ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.MOBEMBDEV.v10.en/mwsdk/html/mwconUnderstandingtheLifeCycleofaMobileControl.htm
 
R

rn5a

Gozirra, could you pleae clarify a few doubts?

Assume that the DataGrid gets bound in the Page_Load sub after every
post back. When the page loads for the first time, the DataGrid is not
in the editable mode. Assume that the second cell in the first row of
the DataGrid (which is a BoundColumn) is "rn5a". Next I click the
"Edit" link (EditCommandColumn). The DataGrid changes to the editable
mode & the second cell in the first row changes to a TextBox with the
Text "rn5a" i.e.

CType(ea.Item.Cells(1).Controls(0), TextBox).Text = "rn5a"

The "Edit" link also gets replaced with "Update" & "Cancel" links. Now
the ViewState of the second cell in the first row of the DataGrid is
"rn5a".

Next I change the Text in this TextBox to "Gozirra" & click the
"Update" link. The ViewState changes to "Gozirra" but since the
DataGrid gets re-bound to the data in the Page_Load sub, "Gozirra"
which comes from the ViewState is lost & "Gozirra" gets overwritten
with the initial value "rn5a". In other words, the second cell in the
first row of the DataGrid reverts back to "rn5a". After this, the
UpdateCommand event of the DataGrid fires which finds that
CType(ea.Item.Cells(1).Controls(0), TextBox).Text is still equal to
"rn5a" & hence the final output is that the original value remains &
the updated value is lost. & this happens because on every post back,
the DataGrid is re-bound in the Page_Load sub before retrieving the
updated value. If the DataGrid is not re-bound after every post back in
the Page_Load sub, the UpdateCommand event (which fires after
Page_Load) would ensure that the updated value is first retrieved &
then the DataGrid is re-bound to the data.

Is this how the logic flows? Please correct me if I am wrong?
 
R

rn5a

Gozirra, could you pleae clarify a few doubts?

Assume that the DataGrid gets bound in the Page_Load sub after every
post back. When the page loads for the first time, the DataGrid is not
in the editable mode. Assume that the second cell in the first row of
the DataGrid (which is a BoundColumn) is "rn5a". Next I click the
"Edit" link (EditCommandColumn). The DataGrid changes to the editable
mode & the second cell in the first row changes to a TextBox with the
Text "rn5a" i.e.

CType(ea.Item.Cells(1).Controls(0), TextBox).Text = "rn5a"

The "Edit" link also gets replaced with "Update" & "Cancel" links. Now
the ViewState of the second cell in the first row of the DataGrid is
"rn5a".

Next I change the Text in this TextBox to "Gozirra" & click the
"Update" link. The ViewState changes to "Gozirra" but since the
DataGrid gets re-bound to the data in the Page_Load sub, "Gozirra"
which comes from the ViewState is lost & "Gozirra" gets overwritten
with the initial value "rn5a". In other words, the second cell in the
first row of the DataGrid reverts back to "rn5a". After this, the
UpdateCommand event of the DataGrid fires which finds that
CType(ea.Item.Cells(1).Controls(0), TextBox).Text is still equal to
"rn5a" & hence the final output is that the original value remains &
the updated value is lost. & this happens because on every post back,
the DataGrid is re-bound in the Page_Load sub before retrieving the
updated value. If the DataGrid is not re-bound after every post back in
the Page_Load sub, the UpdateCommand event (which fires after
Page_Load) would ensure that the updated value is first retrieved &
then the DataGrid is re-bound to the data.

Is this how the logic flows? Please correct me if I am wrong?
 
G

Gozirra

You are mostly correct. I want to clarify one thing that I kind of
lazily stated incorrectly before.

ViewState is actually used to repopulate the data of the controls on
postback. So Initialize runs which creates the controls in memory.
Then the state of the new controls are set using the viewstate. Then
any postback data is checked and the controls updated with any changes
that may be neccessary. In our case, the initial load of the viewstate
put the value rn5a into the textbox. It is during the processing of
the postback data that this value is actually changed to Gozirra. Then
page_load and other events follow, including the update. The final
state of the controls before render is saved to the viewstate for use
during the next trip.

I hope that all makes sense. If not, I'll continue to monitor this
thread and try to answer any other questions that you may have. But I
would say that you have a pretty good understanding of what is going on
and how to code appropriately.
 
R

rn5a

But I would say that you have a pretty good understanding of what is going on
I am flattered.......just joking :)

Well, as of now, I don't have any other queries on this topic but if I
encounter any problems, I will definitely get back to you. & why
wouldn't I? You really seem to have the knack of explaining things very
very lucidly. This isn't the first time you have answered my post & I
have always found that my problems do get resolved as soon as you enter
the "battlefield" :)

Thanks a lot of all your help.

If you don't mind, may I know from which part of the world you are? I
am from Mumbai, India.
 
G

Gozirra

I appreciate the compliment. I always feel I ramble on more than is
neccessary but its nice to know that I was able to help.

I currently reside in St. Louis, Missouri USA.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

DropDownList DataGrid 1
Controls? 15
Dynamic BoundColumn 2
DataBind 1
DatagGrid Cascade Style Sheet CSS 2
Edit Buttons in a datagrid 2
DataGrid.Columns(Index) 3
DataBind In ItemDataBound Event 1

Top