Unable to update GridView bound to DataTable

Last post 04-21-2008 3:16 AM by Pushkar. 10 replies.

Sort Posts:

  • Unable to update GridView bound to DataTable

    04-18-2008, 6:00 PM
    • Loading...
    • bhan
    • Joined on 04-18-2008, 9:32 PM
    • Posts 8

     Hi,

     

    I have the following problem. I'm working on a shopping cart. I collect the items in a DataTable. Then I load those items into a GridView. In the GridView, the user is allowed to change the quantity of each product. So far I've figured out that I need to code the RowUpdating event (I already have RowEditing). Do I also need RowUpdated event?

     I was trying various solutions but none of them worked so far. How do I transfer the new quantity value into the GridView? I would greatly appreciate if anybody could provide me with a step-by-step solution.

    Thanks in advance:) 

    PS. I'm working with VB, and I'm not very familiar with C#

     

    This is the piece of the code I was using:

     

    Line 110:        Dim gvr As GridViewRow = Me.GridView1.Rows(Me.GridView1.EditIndex)
    Line 111: Dim newQ As Integer = CType(gvr.Cells(5).FindControl("Quantity"), TextBox).Text
    Line 112: e.NewValues("Quantity") = newQ
    I get the following error message: 

    Object reference not set to an instance of an object.

     

     

  • Re: Unable to update GridView bound to DataTable

    04-19-2008, 2:54 AM
    • Loading...
    • aamador
    • Joined on 02-11-2008, 10:49 PM
    • Posts 1,105

    I have prepared a simple example to help deal with some of the issues

     

    <%@ Page Language="VB" AutoEventWireup="false" CodeFile="spexample.aspx.vb" Inherits="spexample" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>Untitled Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
        
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
                DataKeyNames="OrderID,Expr1,ProductID" DataSourceID="SqlDataSource1">
                <Columns>
                    <asp:CommandField ShowEditButton="True" />
                    <asp:BoundField DataField="OrderID" HeaderText="OrderID" InsertVisible="False" 
                        ReadOnly="True" SortExpression="OrderID" />
                    <asp:BoundField DataField="CustomerID" HeaderText="CustomerID" 
                        SortExpression="CustomerID" />
                    <asp:BoundField DataField="OrderDate" HeaderText="OrderDate" 
                        SortExpression="OrderDate" />
                    <asp:BoundField DataField="RequiredDate" HeaderText="RequiredDate" 
                        SortExpression="RequiredDate" />
                    <asp:BoundField DataField="ShippedDate" HeaderText="ShippedDate" 
                        SortExpression="ShippedDate" />
                    <asp:BoundField DataField="Expr1" HeaderText="Expr1" ReadOnly="True" 
                        SortExpression="Expr1" />
                    <asp:BoundField DataField="ProductID" HeaderText="ProductID" ReadOnly="True" 
                        SortExpression="ProductID" />
                    <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" 
                        SortExpression="UnitPrice" />
                    <asp:BoundField DataField="Quantity" HeaderText="Quantity" 
                        SortExpression="Quantity" />
                </Columns>
            </asp:GridView>
            <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
                ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
                SelectCommand="SELECT Orders.OrderID, Orders.CustomerID, Orders.OrderDate, Orders.RequiredDate, Orders.ShippedDate, [Order Details].OrderID AS Expr1, [Order Details].ProductID, [Order Details].UnitPrice, [Order Details].Quantity FROM Orders INNER JOIN [Order Details] ON Orders.OrderID = [Order Details].OrderID" 
                UpdateCommand="UPDATE [Order Details] SET ProductID = ProductID, Quantity = Quantity, UnitPrice = UnitPrice">
            </asp:SqlDataSource>
        
        </div>
        </form>
    </body>
    </html>
      
    Partial Class spexample
        Inherits System.Web.UI.Page
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
        End Sub
    
        Protected Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles GridView1.RowUpdating
            ' this is the ideal place to grab data after an edit and before committing
            ' to the database. In this example I am pulling Unitprice and quantity to do some 
            ' calculations
    
            Dim unitprice As Decimal = e.NewValues("UnitPrice")
            Dim quantity As Decimal = e.NewValues("Quantity")
            Dim extended As Decimal = unitprice * quantity
    
            ' The above works because I am binding with a SqlDataSource control but If I use 
            ' Dataset and use DataSource property the above will not work in that case 
    
            Dim uprice As Decimal = Convert.ToDecimal(CType(GridView1.Rows(e.RowIndex).Cells(8).Controls(0), TextBox).Text)
            Dim qty As Decimal = Convert.ToDecimal(CType(GridView1.Rows(e.RowIndex).Cells(9).Controls(0), TextBox).Text)
            Dim ext As Decimal = uprice * qty
    
            ' FindControl usually only works if you have template fields but in the above case I stuck with standard bound
            ' fields and we really don't know what the textbox name are or if it is even possible.
    
            ' At this point you can override the normal update mechanism and use own data access. If you did and you were
            ' using SqlDataSource control then you need to abort the command to update
            e.Cancel = True
    
            ' because this will abort the update it also leaves the grid in edit mode.  to deal with this do 
            GridView1.EditIndex = -1
            GridView1.DataBind()
    
    
    
        End Sub
    End Class
    
     
    I am not anti social, am just not user friendly
  • Re: Unable to update GridView bound to DataTable

    04-19-2008, 10:53 AM
    • Loading...
    • bhan
    • Joined on 04-18-2008, 9:32 PM
    • Posts 8

     Hi,

     Thanks for the fast reply. I've tried your code and it still doesn't work. In my case I do not  have any defined sqldatasource. I'm using a datatable that is stored in session:

     

    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID">
    <Columns>
    <asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID" ReadOnly="True" />
    <asp:BoundField DataField="Product_ID" HeaderText="Product_ID" SortExpression="Product_ID" ReadOnly="True" />
    <asp:BoundField DataField="Product_Name" HeaderText="Product_Name" SortExpression="Product_Name" ReadOnly="True" />
    <asp:BoundField DataField="Price" HeaderText="Price" SortExpression="Price" ReadOnly="True" />
    <asp:BoundField DataField="Quantity" HeaderText="Quantity" SortExpression="Quantity" />
    <asp:CommandField ShowEditButton="True" EditText="Change" />
    </Columns>
    </asp:GridView>
      

     

    1    Imports System
    2 Imports System.IO
    3 Imports System.Data
    4 Imports System.Data.SqlClient
    5 Imports System.Web.UI.HtmlControls
    6 Imports System.Web.UI
    7 Imports System.Web.Security
    8 Imports System.Web.UI.WebControls.Label
    9 Imports System.Web.UI.WebControls.TextBox
    10
    11
    12 Partial Class Cart
    13 Inherits System.Web.UI.Page
    14
    15 Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    16
    17 Dim cart As DataTable
    18
    19 'check if session("Cart") exists
    20 If Session("Cart") Is Nothing Then
    21 Me
    .GridView1.Visible = False
    22 Me
    .btnEmpty.Visible = False
    23 Me
    .lblEmptyCart.Visible = True
    24 Else

    25 cart = CType(Session("Cart"), DataTable)
    26 GridView1.DataSource = cart
    27 GridView1.DataBind()
    28 End If
    29
    30
    31
    32 End Sub
    33
    34
    35
    36 Protected Sub
    GridView1_RowEditing(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles GridView1.RowEditing
    37
    38 GridView1.EditIndex = e.NewEditIndex
    39 GridView1.DataBind()
    40
    41 End Sub
    42
    43 Protected Sub
    GridView1_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles GridView1.RowUpdating
    44
    48
    49 Dim quantity As Integer = e.NewValues("Quantity")
    53
    54 Dim qty As Integer = Convert.ToInt32(CType(GridView1.Rows(e.RowIndex).Cells(5).Controls(0), TextBox).Text)
    55 61 e.Cancel = True
    62 64 GridView1.EditIndex = -1
    65 GridView1.DataBind()
    66
    67
    68

    89
    90 End Sub
    91
    92 End Class

    93

     
     Now the page crashes at line 54 with a message: Unable to cast object of type 'System.Web.UI.WebControls.DataControlLinkButton' to type 'System.Web.UI.WebControls.TextBox'.

     What am I doing wrong?

     

  • Re: Unable to update GridView bound to DataTable

    04-19-2008, 5:22 PM
    Answer
    • Loading...
    • aamador
    • Joined on 02-11-2008, 10:49 PM
    • Posts 1,105

    you may be off in you index value

    You have

     Dim qty As Integer = Convert.ToInt32(CType(GridView1.Rows(e.RowIndex).Cells(5).Controls(0), TextBox).Text)

    Because you button is at the end not in front then the first column is zero.  Try

     Dim qty As Integer = Convert.ToInt32(CType(GridView1.Rows(e.RowIndex).Cells(4).Controls(0), TextBox).Text)

    I think 5 is the button it self

     

    I am not anti social, am just not user friendly
  • Re: Unable to update GridView bound to DataTable

    04-19-2008, 6:34 PM
    • Loading...
    • bhan
    • Joined on 04-18-2008, 9:32 PM
    • Posts 8

     You're right. Now I don't get the error message, but the value is not updated. I guess this is because I only have one way binding so far. Is that correct?

  • Re: Unable to update GridView bound to DataTable

    04-19-2008, 7:31 PM
    • Loading...
    • aamador
    • Joined on 02-11-2008, 10:49 PM
    • Posts 1,105

    Okay, You can go back using the wizard and enable two way binding or you can do it manually by changing the eval's to Bind.  But becareful with this. I use the wizard and watch what it does.  Little issues will kill you and make you waste lots of time.

     

    I am not anti social, am just not user friendly
  • Re: Unable to update GridView bound to DataTable

    04-19-2008, 8:24 PM
    • Loading...
    • bhan
    • Joined on 04-18-2008, 9:32 PM
    • Posts 8

     How can I do that? Do I need to change my columns from databound to item template?

  • Re: Unable to update GridView bound to DataTable

    04-19-2008, 10:07 PM
    • Loading...
    • bhan
    • Joined on 04-18-2008, 9:32 PM
    • Posts 8

     I converted my Quantity column in item template. The data is still not being updated.


    This is code I currently have:

     

    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID">
    <Columns>
    <asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID" ReadOnly="True" />
    <asp:BoundField DataField="Product_ID" HeaderText="Product_ID" SortExpression="Product_ID" ReadOnly="True" />
    <asp:BoundField DataField="Product_Name" HeaderText="Product_Name" SortExpression="Product_Name" ReadOnly="True" />
    <asp:BoundField DataField="Price" HeaderText="Price" SortExpression="Price" ReadOnly="True" />
    <asp:TemplateField HeaderText="Quantity" SortExpression="Quantity">
    <EditItemTemplate>
    <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("Quantity") %>'></asp:TextBox>
    </EditItemTemplate>
    <ItemTemplate>
    <asp:Label ID="Label1" runat="server" Text='<%# Bind("Quantity") %>'></asp:Label>
    </ItemTemplate>
    </asp:TemplateField>
    <asp:CommandField ShowEditButton="True" EditText="Change" />
    </Columns>
    </asp:GridView>
     
     
     
    Imports System
    Imports System.IO
    Imports System.Data
    Imports System.Data.SqlClient
    Imports System.Web.UI.HtmlControls
    Imports System.Web.UI
    Imports System.Web.Security
    Imports System.Web.UI.WebControls.Label
    Imports System.Web.UI.WebControls.TextBox


    Partial Class Cart
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not Page.IsPostBack Then
    If
    Session("Cart") Is Nothing Then
    Me
    .GridView1.Visible = False
    Me
    .btnEmpty.Visible = False
    Me
    .lblEmptyCart.Visible = True
    Else

    BindData()
    'Cart = CType(Session("Cart"), DataTable)
    'GridView1.DataSource = Cart
    'GridView1.DataBind()

    End If
    'BindData()
    End If

    End Sub


    Protected Sub
    btnEmpty_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnEmpty.Click

    Session.Remove("Cart")

    End Sub

    Protected Sub
    GridView1_RowEditing(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles GridView1.RowEditing

    GridView1.EditIndex = e.NewEditIndex
    'GridView1.DataBind()
    BindData()

    End Sub

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

    Dim quantity As Integer = e.NewValues("Quantity")
    Dim qty As Integer = Convert.ToInt32(CType(GridView1.Rows(e.RowIndex).Cells(4).Controls(1), TextBox).Text)


    e.Cancel = True
    GridView1.EditIndex = -1

    BindData()
    Me.lblT.Text = qty.ToString


    End Sub

    Public Sub
    BindData()

    Dim cart As DataTable
    cart = CType(Session("Cart"), DataTable)
    GridView1.DataSource = cart
    GridView1.DataBind()

    End Sub

    End Class
      
      
  • Re: Unable to update GridView bound to DataTable

    04-20-2008, 11:08 AM
    • Loading...
    • bhan
    • Joined on 04-18-2008, 9:32 PM
    • Posts 8

     I managed to update the quantity. However, I had to change my "ID" column to ReadOnly="false". Otherwise, I couldn't extract the value of that field. I was getting a message that the index was out of range of valid values. Does it mean that I cannot get the value of a label? This is the code I was using:

     

            Dim uid As Integer = Convert.ToInt32(CType(GridView1.Rows(e.RowIndex).Cells(0).Controls(0), Label).Text)
    
     

     When I change the field readonly attribute to false (and Label to TextBox in VB code), then I'm able to get the value of that field. But the only field I want to have editable is Quantity.
     

  • Re: Unable to update GridView bound to DataTable

    04-21-2008, 3:00 AM

    Hi bhan ,

    You can use :

    GridView1.Rows(e.RowIndex).FindControl("TextBox1") instead.

    This method retrun one value of Oject type. Remember to cast it to TextBox !

     

    Sincerely,
    Samu Zhang
    Microsoft Online Community Support

    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question.
  • Re: Unable to update GridView bound to DataTable

    04-21-2008, 3:16 AM
    • Loading...
    • Pushkar
    • Joined on 02-17-2006, 7:27 AM
    • http://www.plumtreegroup.net CDIPL - AHD
    • Posts 735

    Correct the line number 112...& see is it working.or not..

    Dim  newQ  as Integer = e.NewValues("Quantity")

     

    "A conclusion is where you got tired of thinking.
    Be different. Think "

    Remember to click “Mark as Answer” on the post If you get answer from my post(s) !

    Thanks Guys
    ------------
    Pushkar
Page 1 of 1 (11 items)
Microsoft Communities