?
Solved

Unable to update GridView data on RowUpdating

Posted on 2007-10-03
12
Medium Priority
?
2,350 Views
Last Modified: 2013-11-07
I've added a gridview to my project, and it's displaying and sorting properly. However, when I click on 'Update' on a row (after clicking'edit' and making a change), I'm not able to find or see the oldvalues or newvalues in GridView1_RowUpdating. I can see that e.RowIndex is set properly, but that's about it. Also, I'm using a cache object, as seen in the code below, and I've never used that before. (I did a datagrid several years ago...). Is the cache needed?
I know this problem is due to late binding, but I like having complete control over my object. I'm not a big fan of drag and drop and then magic server pixies do the rest.

Code In Front:

<%@ Page Language="VB" MasterPageFile="~/MasterPage.master" AutoEventWireup="false" CodeFile="workshopgroups_main.aspx.vb" Inherits="administration_workshopgroups_main" title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    <table bgcolor="<% =System.Configuration.ConfigurationManager.AppSettings.Get("Admin_BGColor")%>" width="100%">
        <tr>
            <td align="center" colspan="3">
                <strong><span class="adminlink"><a href="default.aspx">Calendar Management</a></span>
                    &gt; Workshop Groups</strong></td>
        </tr>
        <tr>
            <td colspan="3">
                &nbsp;</td>
        </tr>
        <tr>
            <td colspan="3">
                <asp:Label ID="lblWorkshopGroups" runat="server"></asp:Label></td>
        </tr>
        <tr>
            <td colspan="3">
                <asp:GridView id="gvWorkShopGroups" runat="server"
                    AutoGenerateColumns="False"
                    HeaderStyle-BackColor="Navy"
                    HeaderStyle-ForeColor="White"
                    HeaderStyle-Font-Bold="True"
                    GridLines="None"
                    AlternatingRowStyle-BackColor="#eeeeee"
                    CellPadding="2"
                    Font-Names="Arial,Verdana"
                    AllowSorting="True" Width="100%" DataKeyNames="id">
                    <Columns>
                        <asp:CommandField ShowEditButton="True">
                            <ItemStyle Width="20px" Wrap="False" />
                        </asp:CommandField>
                        <asp:CommandField ShowDeleteButton="True">
                            <ItemStyle Width="20px" Wrap="False" />
                        </asp:CommandField>
                        <asp:BoundField DataField="Name" HeaderText="Name" >
                            <ItemStyle HorizontalAlign="Left" Wrap="False" />
                            <HeaderStyle HorizontalAlign="Left" />
                        </asp:BoundField>
                        <asp:BoundField DataField="Ordering" HeaderText="Ordering" >
                            <ItemStyle HorizontalAlign="Right" Wrap="False" />
                            <HeaderStyle HorizontalAlign="Right" />
                        </asp:BoundField>
                        <asp:BoundField DataField="id" HeaderText="id" />
                    </Columns>            
                    <HeaderStyle BackColor="Navy" Font-Bold="True" ForeColor="White" />
                    <AlternatingRowStyle BackColor="#EEEEEE" />
                </asp:Gridview>
           
            </td>
        </tr>
    </table>
</asp:Content>

Code Behind:
Imports System.Configuration.ConfigurationManager
Imports System.Data.SqlClient
Imports System.Data
Imports System.Diagnostics

Partial Class administration_workshopgroups_main
    Inherits System.Web.UI.Page
    Dim wsg As workshopgroup
    Dim dt As DataTable
    Dim dv As DataView

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            wsg = New workshopgroup
            dt = New DataTable
            dv = New DataView
            dt = wsg.LoadAll() '<- Returns a datatable with multiple lines and the following fields: id, name, ordering
            dv = New DataView(dt)

            ' Cache the view so we can sort on it later
            ' Is this really needed? I never had to use Cache in the past...
            Cache("dv") = dv
            Cache("dt") = dt
            BindGrid()
        End If
    End Sub

    Private Sub BindGrid()
        'Bind the DataTable to the GridView
        gvWorkShopGroups.DataSource = dt
        gvWorkShopGroups.DataBind()
    End Sub

    Protected Sub gvWorkShopGroups_RowEditing(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles gvWorkShopGroups.RowEditing
        Dim dv As New DataView
        dv = Cache("dv")

        gvWorkShopGroups.DataSource = dv
        gvWorkShopGroups.EditIndex = e.NewEditIndex
        gvWorkShopGroups.DataBind()
    End Sub

    Protected Sub gvWorkShopGroups_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles gvWorkShopGroups.RowUpdating
        Dim row As GridViewRow = gvWorkShopGroups.Rows(e.RowIndex)
        If row IsNot Nothing Then
            ' Below produces nothing
            Debug.WriteLine(row.Cells(0).Text)
            ' This does show the correct row that I am updating ...
            Response.Write(e.RowIndex)
        End If
    End Sub

    Protected Sub gvWorkShopGroups_Sorting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewSortEventArgs) Handles gvWorkShopGroups.Sorting
        Dim dv As New DataView
        dv = Cache("dv")

        dv.Sort = e.SortExpression.ToString() & " DESC"
        gvWorkShopGroups.DataSource = dv
        gvWorkShopGroups.DataBind()
    End Sub
End Class
0
Comment
Question by:L00M
  • 8
  • 4
12 Comments
 
LVL 10

Expert Comment

by:digitalZo
ID: 20005796
Where's the Update query in RowUpdating?

Cache can be used if you're sorting the grid. Otherwise, it's not necessary.
0
 
LVL 11

Author Comment

by:L00M
ID: 20006713
Ah, then that's why I'm using Cache. I probably wont need sorting, but found an example online and thought I'd add it.

As for the update query, it's not specified yet, because I can't find the data that has been changed so I can run an update query. I've found sever 'For Each' examples online to iterate through the 'NewValues' and 'OldValues' collections, but it skips right over the loops, so the collections are empty.
0
 
LVL 11

Author Comment

by:L00M
ID: 20007491
I just added the following code to my RowUpdating event:

    Protected Sub gvWorkShopGroups_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles gvWorkShopGroups.RowUpdating
        Dim row As GridViewRow = gvWorkShopGroups.Rows(e.RowIndex)
        Dim i As Integer
        For i = 0 To row.Cells.Count - 1
            Debug.WriteLine("Cells(" & i & ") = " & row.Cells(i).Text)
        Next
    End Sub

It fires off just fine, but in my debutg window, I see:

Cells(0) =
Cells(1) =
Cells(2) =
Cells(3) =
Cells(4) =

Where are the values? New or old...
I suspect this has something to do with the DataBinding, but am confused on how to implement it.

TIA,
L00M
0
Veeam and MySQL: How to Perform Backup & Recovery

MySQL and the MariaDB variant are among the most used databases in Linux environments, and many critical applications support their data on them. Watch this recorded webinar to find out how Veeam Backup & Replication allows you to get consistent backups of MySQL databases.

 
LVL 10

Accepted Solution

by:
digitalZo earned 2000 total points
ID: 20007970
Well, you want to just update, right?

Try this:

    Protected Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles GridView1.RowUpdating

    Dim SNo = GridView1.DataKeys(e.RowIndex).Value

    Dim Name As New System.Web.UI.WebControls.TextBox
    Name = CType(Me.GridView1.Rows(e.RowIndex).Cells([cellnumber]).Controls(0), TextBox)
    Dim vName As String = Name.Text

    [UPDATE QUERY]

    GridView1.EditIndex = -1
    BindGrid()
    End Sub

Or instead of this:

  Dim FieldName1 As New System.Web.UI.WebControls.TextBox
    FieldName1 = CType(Me.GridView1.Rows(e.RowIndex).Cells([cellnumber]).Controls(0), TextBox)
    Dim FName As String = FieldName1.Text


You can try this:

Dim row As GridViewRow = GridView1.Rows(e.RowIndex)

Dim FieldName1 As TextBox = row.FindControl("FieldName1")
Dim fname As String = FieldName1.Text

This should update!
0
 
LVL 11

Author Comment

by:L00M
ID: 20008161
Well slap my behind and call me Polly!
It seems like that's going to work digitalZo....

Lemme do some more testing, but it looks like you get the gold star.
0
 
LVL 11

Author Comment

by:L00M
ID: 20008321
Looks like that will work. Can you clear up one more detail? You're getting the poinks no matter what.

I'm adding the ID column to the datagrid as well, but there is no need for the end user to actually see the id, I just need it for updating. However, when I set that column to 'visible=false', I'm unable to retrieve the value. The CType works, and when I debug, I can see it automatically sets the new textbox 'ToolTip' to ID, so that's a good sign. But the 'text' property is blank.

Thanks!
0
 
LVL 10

Expert Comment

by:digitalZo
ID: 20008839
Have you set the DataKey in GridView? If not, then set the DataKey to ID [in the Source code] and this code should only retrieve the value, not edit or update it [unless you specify the TextBox thing]:

<asp:GridView DataKeyNames="ID" . . . >

Protected Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles GridView1.RowUpdating

Dim ID = GridView1.DataKeys(e.RowIndex).Value

0
 
LVL 11

Author Comment

by:L00M
ID: 20048350
My apologies for not responding sooner. Busy busy.

Ok, I can successfully return the new values using the code:

        id = gvWorkShopGroups.DataKeys(e.RowIndex).Value
        tb = CType(Me.gvWorkShopGroups.Rows(e.RowIndex).Cells(2).Controls(0), TextBox)
        NewName = tb.Text
        tb = CType(Me.gvWorkShopGroups.Rows(e.RowIndex).Cells(3).Controls(0), TextBox)
        NewOrdering = tb.Text

However, per your suggection, I'd like to use the following code as it is cleaner:

        id = gvWorkShopGroups.DataKeys(e.RowIndex).Value
        Dim row As GridViewRow = Me.gvWorkShopGroups.Rows(e.RowIndex)
        Dim NewName As TextBox = row.FindControl("name")
        Dim NewOrdering As TextBox = row.FindControl("ordering")

However, nothing is returned into those variables. When debugging, I can see 'row' is populated, and has cell values available, but I'm guessing the cells aren't named and can only be referred to by index number. Since the grid will be dynamically populated, how to I give the columns proper names? (Assuming I've diagnosed the problem correctly.)
0
 
LVL 11

Author Comment

by:L00M
ID: 20052423
Got it. After converting all fields to Template fieldsd, I was able to access everything properly.

Thanks for all your help!
0
 
LVL 10

Expert Comment

by:digitalZo
ID: 20054519
Glad it worked.

The cleaner code you suggested didn't actually work for me. The alternative one worked, which is why I posted that one.

Cheers.
0
 
LVL 11

Author Closing Comment

by:L00M
ID: 31408006
Thanks Zo!
0
 
LVL 11

Author Comment

by:L00M
ID: 20328424
Thanks Zo. I forgot I had this question open. Sorry so long in responding.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Problem Hi all,    While many today have fast Internet connection, there are many still who do not, or are connecting through devices with a slower connect, so light web pages and fast load times are still popular.    If your ASP.NET page …
In real business world data are crucial and sometimes data are shared among different information systems. Hence, an agreeable file transfer protocol need to be established.
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Suggested Courses

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question