Hi nsds,
Refer below sample.
HTML
<asp:GridView ID="gvStudents" runat="server" AutoGenerateColumns="false" CssClass="Grid" DataKeyNames="StudentId">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:ImageButton ID="imgShow" runat="server" OnClick="Show_Hide_ChildGrid"
                    ImageUrl="~/images/plus.png" CommandArgument="Show" />
                <asp:Panel ID="pnlNested" runat="server" Visible="false" Style="position: relative">
                    <asp:GridView ID="gvNested" runat="server" AutoGenerateColumns="false" PageSize="3"
                        AllowPaging="true" OnPageIndexChanging="OnChildGrid_PageIndexChanging" CssClass="ChildGrid"
                        AutoGenerateEditButton="true" OnRowEditing="gvNested_RowEditing"
                        OnRowCancelingEdit="gvNested_RowCancelingEdit" ShowHeader="false">
                        <Columns>
                            <asp:BoundField DataField="staff_id" HeaderText="Staff Id" ReadOnly="true" />
                            <asp:BoundField DataField="TotalMarks" HeaderText="Total Marks" />
                            <asp:BoundField DataField="Rank" HeaderText="Rank" ReadOnly="true" />
                        </Columns>
                    </asp:GridView>
                </asp:Panel>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="StudentName" HeaderText="Student Name" />
    </Columns>
</asp:GridView>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
    $(function () {
        $("[src*=minus]").each(function () {
            $(this).closest("tr").after("<tr><td></td><td colspan = '999'>" + $(this).next().html() + "</td></tr>");
            $(this).next().remove()
        });
    });
</script>
Namespaces
C#
using System.Data;
VB.Net
Imports System.Data
Code
C#
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        DataTable dt = new DataTable();
        dt.Columns.AddRange(new DataColumn[] {
                            new DataColumn("StudentId"),
                            new DataColumn("StudentName") });
        dt.Rows.Add("XXX001", " Rahul");
        dt.Rows.Add("XXX002", "Madhav");
        dt.Rows.Add("XXX003", "Ranbir");
        gvStudents.DataSource = dt;
        gvStudents.DataBind();
    }
}
protected void Show_Hide_ChildGrid(object sender, EventArgs e)
{
    ImageButton imgShowHide = (sender as ImageButton);
    GridViewRow row = (imgShowHide.NamingContainer as GridViewRow);
    if (imgShowHide.CommandArgument == "Show")
    {
        row.FindControl("pnlNested").Visible = true;
        imgShowHide.CommandArgument = "Hide";
        imgShowHide.ImageUrl = "~/images/minus.png";
        string id = gvStudents.DataKeys[row.RowIndex].Value.ToString();
        GridView gvNested = row.FindControl("gvNested") as GridView;
        gvNested.ToolTip = id;
        BindStudentDetails(id, gvNested);
    }
    else
    {
        row.FindControl("pnlNested").Visible = false;
        imgShowHide.CommandArgument = "Show";
        imgShowHide.ImageUrl = "~/images/plus.png";
    }
}
protected void OnChildGrid_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    GridView gvNested = (sender as GridView);
    gvNested.PageIndex = e.NewPageIndex;
    BindStudentDetails(gvNested.ToolTip, gvNested);
}
protected void gvNested_RowEditing(object sender, GridViewEditEventArgs e)
{
    GridView gvNested = sender as GridView;
    GridViewRow currentRow = gvNested.Rows[e.NewEditIndex];
    gvNested.EditIndex = e.NewEditIndex;
    BindStudentDetails(gvNested.ToolTip, gvNested);
}
protected void gvNested_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
    GridView gvNested = (sender as GridView);
    gvNested.EditIndex = -1;
    BindStudentDetails(gvNested.ToolTip, gvNested);
}
private void BindStudentDetails(string id, GridView gvNested)
{
    gvNested.ToolTip = id;
    DataTable dt = new DataTable();
    dt.Columns.AddRange(new DataColumn[] {
                            new DataColumn("StudentId"),
                            new DataColumn("TotalMarks"),
                            new DataColumn("Rank"),
                            new DataColumn("staff_id") });
    dt.Rows.Add("XXX001", "800", "5", "staff_ABC");
    dt.Rows.Add("XXX002", "400", "4", "staff_DEF");
    dt.Rows.Add("XXX003", "1000", "1", "staff_DEF");
    DataTable dtFilter = dt.Select("StudentId='" + id + "'").CopyToDataTable();
    gvNested.DataSource = dtFilter;
    gvNested.DataBind();
}
VB.Net
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    If Not IsPostBack Then
        Dim dt As DataTable = New DataTable()
        dt.Columns.AddRange(New DataColumn() {
                            New DataColumn("StudentId"),
                            New DataColumn("StudentName")})
        dt.Rows.Add("XXX001", " Rahul")
        dt.Rows.Add("XXX002", "Madhav")
        dt.Rows.Add("XXX003", "Ranbir")
        gvStudents.DataSource = dt
        gvStudents.DataBind()
    End If
End Sub
Protected Sub Show_Hide_ChildGrid(ByVal sender As Object, ByVal e As EventArgs)
    Dim imgShowHide As ImageButton = (TryCast(sender, ImageButton))
    Dim row As GridViewRow = (TryCast(imgShowHide.NamingContainer, GridViewRow))
    If imgShowHide.CommandArgument = "Show" Then
        row.FindControl("pnlNested").Visible = True
        imgShowHide.CommandArgument = "Hide"
        imgShowHide.ImageUrl = "~/images/minus.png"
        Dim id As String = gvStudents.DataKeys(row.RowIndex).Value.ToString()
        Dim gvNested As GridView = TryCast(row.FindControl("gvNested"), GridView)
        gvNested.ToolTip = id
        BindStudentDetails(id, gvNested)
    Else
        row.FindControl("pnlNested").Visible = False
        imgShowHide.CommandArgument = "Show"
        imgShowHide.ImageUrl = "~/images/plus.png"
    End If
End Sub
Protected Sub OnChildGrid_PageIndexChanging(ByVal sender As Object, ByVal e As GridViewPageEventArgs)
    Dim gvNested As GridView = (TryCast(sender, GridView))
    gvNested.PageIndex = e.NewPageIndex
    BindStudentDetails(gvNested.ToolTip, gvNested)
End Sub
Protected Sub gvNested_RowEditing(ByVal sender As Object, ByVal e As GridViewEditEventArgs)
    Dim gvNested As GridView = TryCast(sender, GridView)
    Dim currentRow As GridViewRow = gvNested.Rows(e.NewEditIndex)
    gvNested.EditIndex = e.NewEditIndex
    BindStudentDetails(gvNested.ToolTip, gvNested)
End Sub
Protected Sub gvNested_RowCancelingEdit(ByVal sender As Object, ByVal e As GridViewCancelEditEventArgs)
    Dim gvNested As GridView = (TryCast(sender, GridView))
    gvNested.EditIndex = -1
    BindStudentDetails(gvNested.ToolTip, gvNested)
End Sub
Private Sub BindStudentDetails(ByVal id As String, ByVal gvNested As GridView)
    gvNested.ToolTip = id
    Dim dt As DataTable = New DataTable()
    dt.Columns.AddRange(New DataColumn() {
                        New DataColumn("StudentId"),
                        New DataColumn("TotalMarks"),
                        New DataColumn("Rank"),
                        New DataColumn("staff_id")})
    dt.Rows.Add("XXX001", "800", "5", "staff_ABC")
    dt.Rows.Add("XXX002", "400", "4", "staff_DEF")
    dt.Rows.Add("XXX003", "1000", "1", "staff_DEF")
    Dim dtFilter As DataTable = dt.Select("StudentId='" & id & "'").CopyToDataTable()
    gvNested.DataSource = dtFilter
    gvNested.DataBind()
End Sub
Screenshot
