How I show a nested DataView?

EvansGxz 121 Reputation points
2021-06-14T20:22:59.23+00:00

Hello, i watch and saw many examples to scroll a nested gridview, I have an example of one, but doesn't work, I can't scroll it, im doing something wrong?

C#:

protected void Page_Load(object sender, EventArgs e)  
             {  
                 if (!IsPostBack)  
                 {  
                     ViewState["Search"] = "All";  
                     ViewState["Search1"] = "All";  
                     BindName();  
                     BindTotal();  
          
                     gvStudents.DataSource = GetData("select * from Student");  
                     gvStudents.DataBind();  
                 }  
             }         
          
             private void BindTotal()  
             {  
                 SqlConnection con = new SqlConnection(@"Data Source=DESKTOP-A3KJHD1\SQLEXPRESS;Initial Catalog=aptiv;Integrated Security=SSPI");  
                 DataTable dt1 = new DataTable();  
          
                 SqlDataAdapter da1 = new SqlDataAdapter();  
                 SqlCommand cmd1 = new SqlCommand("GetTotal");  
                 cmd1.CommandType = CommandType.StoredProcedure;  
                 cmd1.Parameters.AddWithValue("@Search", ViewState["Search1"].ToString());  
                 cmd1.Connection = con;  
                 da1.SelectCommand = cmd1;  
                 da1.Fill(dt1);  
                 gvStudents.DataSource = dt1;  
                 gvStudents.DataBind();  
                 DropDownList ddlTotal =  
                     (DropDownList)gvStudents.HeaderRow.FindControl("ddlTotal");  
                 this.BindTotalList(ddlTotal);  
             }  
             private void BindName()  
             {  
                 SqlConnection con = new SqlConnection(@"Data Source=DESKTOP-A3KJHD1\SQLEXPRESS;Initial Catalog=aptiv;Integrated Security=SSPI");  
                 DataTable dt = new DataTable();  
          
                 SqlDataAdapter da = new SqlDataAdapter();  
                 SqlCommand cmd = new SqlCommand("GetName");  
                 cmd.CommandType = CommandType.StoredProcedure;  
                 cmd.Parameters.AddWithValue("@Search", ViewState["Search"].ToString());  
                 cmd.Connection = con;  
                 da.SelectCommand = cmd;  
                 da.Fill(dt);  
                 gvStudents.DataSource = dt;  
                 gvStudents.DataBind();  
                 DropDownList ddlName =  
                     (DropDownList)gvStudents.HeaderRow.FindControl("ddlName");  
                 this.BindNameList(ddlName);  
             }  
             private void BindNameList(DropDownList ddlName)  
             {  
                 SqlConnection con = new SqlConnection(@"Data Source=DESKTOP-A3KJHD1\SQLEXPRESS;Initial Catalog=aptiv;Integrated Security=SSPI");  
                 SqlDataAdapter sda = new SqlDataAdapter();  
                 SqlCommand cmd = new SqlCommand("select * from Student");  
          
                 cmd.Connection = con;  
                 con.Open();  
                 ddlName.DataSource = cmd.ExecuteReader();  
                 ddlName.DataTextField = "Name";  
                 ddlName.DataValueField = "Name";  
                 ddlName.DataBind();  
                 con.Close();  
                 ddlName.Items.FindByValue(ViewState["Search"].ToString())  
                         .Selected = true;  
             }  
             private void BindTotalList(DropDownList ddlTotal)  
             {  
                 SqlConnection con = new SqlConnection(@"Data Source=DESKTOP-A3KJHD1\SQLEXPRESS;Initial Catalog=aptiv;Integrated Security=SSPI");  
                 SqlDataAdapter sda = new SqlDataAdapter();  
                 SqlCommand cmd = new SqlCommand("select * from Student");  
          
                 cmd.Connection = con;  
                 con.Open();  
                 ddlTotal.DataSource = cmd.ExecuteReader();  
                 ddlTotal.DataTextField = "Total";  
                 ddlTotal.DataValueField = "Total";  
                 ddlTotal.DataBind();  
                 con.Close();  
                 ddlTotal.Items.FindByValue(ViewState["Search1"].ToString())  
                         .Selected = true;  
             }  
             protected void NameChanged(object sender, EventArgs e)  
             {  
                 DropDownList ddlName = (DropDownList)sender;  
                 ViewState["Search"] = ddlName.SelectedValue;  
                 this.BindName();  
             }  
             protected void TotalChanged(object sender, EventArgs e)  
             {  
                 DropDownList ddlTotal = (DropDownList)sender;  
                 ViewState["Search1"] = ddlTotal.SelectedValue;  
                 this.BindTotal();  
             }  
             private static DataTable GetData(string query)  
             {  
                 SqlConnection con = new SqlConnection(@"Data Source=DESKTOP-A3KJHD1\SQLEXPRESS;Initial Catalog=aptiv;Integrated Security=SSPI");  
          
                 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 StudentId = gvStudents.DataKeys[e.Row.RowIndex].Value.ToString();  
                     GridView gvDetails = e.Row.FindControl("gvDetails") as GridView;  
                     gvDetails.DataSource = GetData(string.Format("select * from Student where id='" + StudentId + "'"));  
                     gvDetails.DataBind();  
                 }  
             }  

JS:

$("[src*=Up]").live("click", function () {  
              $(this).closest("tr").after("<tr><td></td><td colspan = '1000'>" + $(this).next().html() + "</td></tr>")  
              $(this).attr("src", "images/Down.jpg");  
          });  
          $("[src*=Down]").live("click", function () {  
              $(this).attr("src", "images/Up.jpg");  
              $(this).closest("tr").next().remove();  
          });  

HTML:

<asp:GridView ID="gvStudents" runat="server" AutoGenerateColumns="false"  
DataKeyNames="id" OnRowDataBound="OnRowDataBound">  
<Columns>  
  
             <asp:TemplateField>  
                 <ItemTemplate>  
                     <img alt = "" style="height:10px;" src="images/Up.jpg" />  
                     <asp:Panel ID="pnlDetails" runat="server" Style="display: none">  
                         <asp:GridView ID="gvDetails" runat="server" AutoGenerateColumns="false" >  
                             <Columns>  
                                 <asp:BoundField ItemStyle-Width="150px" DataField="id" HeaderText="id" />  
                                 <asp:BoundField ItemStyle-Width="150px" DataField="age" HeaderText="age" />  
                                 <asp:BoundField ItemStyle-Width="150px" DataField="Class" HeaderText="Class" />  
                                 <asp:BoundField ItemStyle-Width="150px" DataField="s_Address" HeaderText="Address" />  
                                 <asp:BoundField ItemStyle-Width="150px" DataField="Phone" HeaderText="Phone" />  
                             </Columns>  
                         </asp:GridView>  
                     </asp:Panel>  
                 </ItemTemplate>  
             </asp:TemplateField>  
             <asp:TemplateField>  
         <HeaderTemplate>  
             Name:  
             <asp:DropDownList ID="ddlName" runat="server"  
             OnSelectedIndexChanged = "NameChanged" AutoPostBack = "true"  
             AppendDataBoundItems = "true">  
              <asp:ListItem Text = "Select" Value = "Select"></asp:ListItem>  
             <asp:ListItem Text = "All" Value = "All"></asp:ListItem>  
                  
             </asp:DropDownList>  
         </HeaderTemplate>  
         <ItemTemplate>  
             <%# Eval("Name") %>  
         </ItemTemplate>  
     </asp:TemplateField>  
            <asp:TemplateField>  
         <HeaderTemplate>  
             Total:  
             <asp:DropDownList ID="ddlTotal" runat="server"  
             OnSelectedIndexChanged = "TotalChanged" AutoPostBack = "true"  
             AppendDataBoundItems = "true">  
              <asp:ListItem Text = "Select" Value = "Select"></asp:ListItem>  
             <asp:ListItem Text = "All" Value = "All"></asp:ListItem>  
             <asp:ListItem Text = "Greater Than 90" Value = "90"></asp:ListItem>  
             <asp:ListItem Text = "Less Than 30" Value = "30"></asp:ListItem>  
                  
             </asp:DropDownList>  
         </HeaderTemplate>  
         <ItemTemplate>  
             <%# Eval("Total") %>  
         </ItemTemplate>  
     </asp:TemplateField>  
          
                 
         </Columns>  
     </asp:GridView>  
     </ContentTemplate>  
     </asp:UpdatePanel>  
     </form>  
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,506 questions
JavaScript API
JavaScript API
An Office service that supports add-ins to interact with objects in Office client applications.
996 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,006 questions
{count} votes

Accepted answer
  1. Albert Kallal 5,256 Reputation points
    2021-06-18T17:16:25.67+00:00

    Ok, great!

    So, a gridview is wonderful for display a grid of data. However, we "often" want a UI in which we click on a single row (or some + button to expand.

    The problem is that the grid view is great for columns, but we can't have a control or something that expands to another row.

    Say we have a grid view of Hotels, and we want to see/view the people booked in that hotel, so the grid view can look like this:

    107089-image.png

    And when we hit the + button, we then "try" to display the child grid. But you get this:

    107172-image.png

    As you can see, it makes a real mess - and it not easy.

    (the reason is we can't really get that additonal control to span the whole grid - there is "poor" column span support for grid view.

    however, what we can do, is use the super duper all amazing ListView. And the list viewe DOES let us nest or drop in a gridview. And with column spanning support (which ListView has), then this becomes rather ease - and I think the results for the LITTLE amount of work is really impressive.

    Ok, so lets use a ListView. I often use the wizards to create the ListView, and THEN we delete all of the tempaltes (edit/alternating, selecte etc.). So, we wind up with not much markup.

    So, here is our ListView markup - note how we dropped in a gridview INSIDE the LV.

    107152-image.png

    Not really too much markup - considering this is a listview AND a gridview. Note close in above the colspan=5 feature - that's the magic trick here!!

    Ok, now our code to fill out this listview:

    It not much:

           protected void Page_Load(object sender, System.EventArgs e)  
            {  
                if (!IsPostBack)  
                    LoadGrid();  
            }  
      
            public void LoadGrid()  
            {  
                string strSQL = "SELECT * FROM tblHotels  ORDER BY HotelName";     
                using (SqlCommand cmdSQL = new SqlCommand(strSQL,   
                      new SqlConnection(Properties.Settings.Default.TEST4)))  
                {  
                    cmdSQL.Connection.Open();  
                    ListView1.DataSource = cmdSQL.ExecuteReader();  
                    ListView1.DataBind();  
                }  
            }  
    

    --
    Ok, so far so good. The output now looks VERY much like the gridview, with this:

    107136-image.png

    So, now all we have to do is wire up that "+" button when we click on it.

    and this is REALLY the cherry on top - super simple!!!
    So simple, lets EVEN add code that if you hit + again, the display will colipase.

    So, the code for "+" button event is this:

            protected void ListView1_SelectedIndexChanged(object sender, EventArgs e)  
            {  
                ListViewDataItem gVR = ListView1.Items[ListView1.SelectedIndex];  
                GridView gChild = (GridView)gVR.FindControl("GridView2");   // pluck grid row  
      
                if (gChild.Style["display"] == "normal")  
                {  
                    // if grid is already display, then hide it, and exit  
                    gChild.Style["display"] = "none";  
                    return;  
                }  
                gChild.Style["display"] = "normal";  
      
                int HotelPK = (int)ListView1.SelectedDataKey.Value;  
                string strSQL = "SELECT * from People where hotel_id = " + HotelPK.ToString();  
      
                using (SqlCommand cmdSQL = new SqlCommand(strSQL,   
                                        new SqlConnection(Properties.Settings.Default.TEST4)))  
                {  
                    cmdSQL.Connection.Open();  
                    gChild.DataSource = cmdSQL.ExecuteReader();  
                    gChild.DataBind();  
                }  
            }  
      
            protected void ListView1_SelectedIndexChanging(object sender, ListViewSelectEventArgs e)  
            {  
      
            }  
      
    

    Note that you DO NEED the 2nd blank SelectedIndexChanging - we don't use it, but it DOES trigger when you directly modify the ListView - so include this blank stub.

    Now, I have to say, we did NOT write very much code, and the result is now this:

    107182-image.png

    Is that not great?

    So using a listview means we CAN nest and get the grid to "take up a whole row".

    ListView allows you to create controls that are more then one row of data. And we can as above shows even drop in a whole gridview - and have it take that that extra row.

    In ALL of the examples I have posted in help forms everywhere?

    I think the above is the most UI, and most usefull, and yet is also not much code or in fact markup at all.

    Setting up a treeview, or a expanding UI in most cases is a HUGE amount of work and code, yet above really shows the power of asp.net - when done right , such solutions produce great UI, and don't require all that much code. I count about 8 lines of code for a expanding + hiding grid of data!!!

    Regards,
    Albert D. Kallal (Access MVP 2003-2017)
    Edmonton, Alberta Canada

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.