Update record in Nested ASP.Net GridView on Button Click using C# and VB.Net

Last Reply 7 months ago By pandeyism

Posted 7 months ago

I have an interface I am creating using vb.net that has two gridviews: header and detail. The functionality today works that if you select a header line, the detail shows up at the bottom of the first grid. 

The interface allows in-line editing on both the header and detail which updates a SQL database where the data is stored. 

I would like to be able to select a header transaction and have the details come up below (nested). 

I have attempted to do this, but most of my code behind comes up with errors as the details gridview loses references. I am looking for some guidance on how to make this change. 

I am looking for the ability to "nest" the second gridview under the line you select. It would behave like a expand and collapse kind of like this:

Nested GridView with Expand Collapse example in ASP.Net using C# and VB.Net

The difference is that I would like to edit rows in both gridviews using onclick and ontexchange events so the user does not need to select edit mode.

You are viewing reply posted by: pandeyism 7 months ago.
Posted 7 months ago

Hey Warren,

Please refer below sample.

Database

For this example I have used of Northwind database that you can download using the link given below.

Download Northwind Database

HTML

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
    $("[src*=plus]").live("click", function () {
        $(this).closest("tr").after("<tr><td></td><td colspan = '999'>" + $(this).next().html() + "</td></tr>")
        $(this).attr("src", "images/minus.png");
    });
    $("[src*=minus]").live("click", function () {
        $(this).attr("src", "images/plus.png");
        $(this).closest("tr").next().remove();
    });
</script>
<asp:GridView ID="gvCustomers" runat="server" AutoGenerateColumns="false" CssClass="Grid"
    DataKeyNames="CustomerID" OnRowDataBound="OnRowDataBound">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <img alt="" style="cursor: pointer" src="images/plus.png" />
                <asp:Panel ID="pnlOrders" runat="server" Style="display: none">
                    <asp:GridView ID="gvOrders" runat="server" AutoGenerateColumns="false" CssClass="ChildGrid">
                        <Columns>
                            <asp:TemplateField HeaderText="OrderId">
                                <ItemTemplate>
                                    <asp:TextBox ID="txtOrderId" runat="server" Text='<%#Eval("OrderId") %>' />
                                </ItemTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField HeaderText="OrderId">
                                <ItemTemplate>
                                    <asp:TextBox ID="txtDate" runat="server" Text='<%#Eval("OrderDate") %>' />
                                </ItemTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField HeaderText="OrderId">
                                <ItemTemplate>
                                    <asp:Button Text="Update" runat="server" OnClick="gvOrders_Update" />
                                </ItemTemplate>
                            </asp:TemplateField>
                        </Columns>
                    </asp:GridView>
                </asp:Panel>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="ContactName">
            <ItemTemplate>
                <asp:TextBox ID="txtName" runat="server" Text='<%#Eval("ContactName") %>' />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="City">
            <ItemTemplate>
                <asp:TextBox ID="txtCity" runat="server" Text='<%#Eval("City") %>' />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Update">
            <ItemTemplate>
                <asp:Button Text="Update" runat="server" OnClick="gvCustomers_Update" />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

Namespaces

C#

using System.Data;
using System.Data.SqlClient;
using System.Configuration;

VB.Net

Imports System.Data.SqlClient
Imports System.Data

Code

C#

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        gvCustomers.DataSource = GetData("select top 10 * from Customers");
        gvCustomers.DataBind();
    }
}

private static DataTable GetData(string query)
{
    string strConnString = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    using (SqlConnection con = new SqlConnection(strConnString))
    {
        using (SqlCommand cmd = new SqlCommand())
        {
            cmd.CommandText = query;
            using (SqlDataAdapter sda = new SqlDataAdapter())
            {
                cmd.Connection = con;
                sda.SelectCommand = cmd;
                using (DataSet ds = new DataSet())
                {
                    DataTable dt = new DataTable();
                    sda.Fill(dt);
                    return dt;
                }
            }
        }
    }
}

protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        string customerId = gvCustomers.DataKeys[e.Row.RowIndex].Value.ToString();
        GridView gvOrders = e.Row.FindControl("gvOrders") as GridView;
        gvOrders.DataSource = GetData(string.Format("select top 3 * from Orders where CustomerId='{0}'", customerId));
        gvOrders.DataBind();
    }
}

protected void gvCustomers_Update(object sender, EventArgs e)
{
    Button btn = (Button)sender;
    GridViewRow gvr = (GridViewRow)btn.NamingContainer;
    TextBox txtName = gvr.FindControl("txtName") as TextBox;
    TextBox txtCity = gvr.FindControl("txtCity") as TextBox;
    //update code.
    ScriptManager.RegisterStartupScript(this, this.GetType(), "CropImage", "alert('Name is : " + txtName.Text + ", City is " + txtCity.Text + "');", true);
}

protected void gvOrders_Update(object sender, EventArgs e)
{
    Button btn = (Button)sender;
    GridViewRow row = (GridViewRow)btn.NamingContainer;
    string txtId = (row.FindControl("txtOrderId") as TextBox).Text;
    string txtDate = (row.FindControl("txtDate") as TextBox).Text;
    int index = txtId.IndexOf(",");
    string OrderId = txtId.Substring(index + 1);
    index = txtDate.IndexOf(",");
    string orderDate = txtDate.Substring(index + 1);
    // Update code.
    ScriptManager.RegisterStartupScript(this, this.GetType(), "CropImage", "alert('Order Id is : " + OrderId + ", Date is : " + orderDate + "');", true);
}

VB.Net

Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    If Not IsPostBack Then
        gvCustomers.DataSource = GetData("select top 10 * from Customers")
        gvCustomers.DataBind()
    End If
End Sub

Private Shared Function GetData(ByVal query As String) As DataTable
    Dim strConnString As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
    Using con As SqlConnection = New SqlConnection(strConnString)
        Using cmd As SqlCommand = New SqlCommand()
            cmd.CommandText = query
            Using sda As SqlDataAdapter = New SqlDataAdapter()
                cmd.Connection = con
                sda.SelectCommand = cmd
                Using ds As DataSet = New DataSet()
                    Dim dt As DataTable = New DataTable()
                    sda.Fill(dt)
                    Return dt
                End Using
            End Using
        End Using
    End Using
End Function

Protected Sub OnRowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
    If e.Row.RowType = DataControlRowType.DataRow Then
        Dim customerId As String = gvCustomers.DataKeys(e.Row.RowIndex).Value.ToString()
        Dim gvOrders As GridView = TryCast(e.Row.FindControl("gvOrders"), GridView)
        gvOrders.DataSource = GetData(String.Format("select top 3 * from Orders where CustomerId='{0}'", customerId))
        gvOrders.DataBind()
    End If
End Sub

Protected Sub gvCustomers_Update(ByVal sender As Object, ByVal e As EventArgs)
    Dim btn As Button = CType(sender, Button)
    Dim gvr As GridViewRow = CType(btn.NamingContainer, GridViewRow)
    Dim txtName As TextBox = TryCast(gvr.FindControl("txtName"), TextBox)
    Dim txtCity As TextBox = TryCast(gvr.FindControl("txtCity"), TextBox)
    ' Update code.
    ScriptManager.RegisterStartupScript(Me, Me.GetType(), "CropImage", "alert('Name is : " & txtName.Text & ", City is " + txtCity.Text & "');", True)
End Sub

Protected Sub gvOrders_Update(ByVal sender As Object, ByVal e As EventArgs)
    Dim btn As Button = CType(sender, Button)
    Dim row As GridViewRow = CType(btn.NamingContainer, GridViewRow)
    Dim txtId As String = (TryCast(row.FindControl("txtOrderId"), TextBox)).Text
    Dim txtDate As String = (TryCast(row.FindControl("txtDate"), TextBox)).Text
    Dim index As Integer = txtId.IndexOf(",")
    Dim OrderId As String = txtId.Substring(index + 1)
    index = txtDate.IndexOf(",")
    Dim orderDate As String = txtDate.Substring(index + 1)
    ' Update code.
    ScriptManager.RegisterStartupScript(Me, Me.GetType(), "CropImage", "alert('Order Id is : " & OrderId & ", Date is : " & orderDate & "');", True)
End Sub

Screenshot