dropdown in gridview dependent on another dropdown.

 here is what  i tried

aspx

<asp:GridView ID="gvProgram" runat="server" DataKeyNames="ChoiceName" AutoGenerateColumns="False" OnRowDataBound="gvProgram_RowDataBound" Width="100%" BackColor="White" BorderColor="#CCCCCC" BorderStyle="None" BorderWidth="1px" CellPadding="3">
    <Columns>
        <asp:BoundField DataField="ChoiceName" HeaderText="Choice" ItemStyle-Width="20%" />
        <asp:TemplateField HeaderText="Program">
            <ItemTemplate>
                <asp:DropDownList ID="ddlProgram" runat="server" class="form-control form-control-sm  mb-9" OnSelectedIndexChanged="ddlProgram_SelectedIndexChanged" AutoPostBack="true">
                    <asp:ListItem Value="0">Select Program</asp:ListItem>

                </asp:DropDownList>
                <asp:RequiredFieldValidator ID="rfvddlProgram" runat="server" ErrorMessage="*" ControlToValidate="ddlProgram" Font-Bold="False" Font-Names="Verdana" Font-Size="8pt"
                    SetFocusOnError="True" ValidationGroup="v1" ForeColor="Red" InitialValue="0"></asp:RequiredFieldValidator>
                <%--  <a href="#" target="_blank">BA Economics</a>--%>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Location">
            <ItemTemplate>
                <asp:DropDownList ID="ddl_Location" runat="server" class="form-control form-control-sm  mb-9">
                    <asp:ListItem Value="0">Select Location</asp:ListItem>

                </asp:DropDownList>
                <asp:RequiredFieldValidator ID="rfvddlLocation" runat="server" ErrorMessage="*" ControlToValidate="ddl_Location" Font-Bold="False" Font-Names="Verdana" Font-Size="8pt"
                    SetFocusOnError="True" ValidationGroup="v1" ForeColor="Red" InitialValue="0"></asp:RequiredFieldValidator>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
    <FooterStyle BackColor="White" ForeColor="#000066" />
    <HeaderStyle BackColor="#6777ef" Font-Bold="True" ForeColor="White" />
    <PagerStyle BackColor="White" ForeColor="#000066" HorizontalAlign="Left" />
    <RowStyle ForeColor="#000066" />
    <SelectedRowStyle BackColor="#669999" Font-Bold="True" ForeColor="White" />
    <SortedAscendingCellStyle BackColor="#F1F1F1" />
    <SortedAscendingHeaderStyle BackColor="#007DBB" />
    <SortedDescendingCellStyle BackColor="#CAC9C9" />
    <SortedDescendingHeaderStyle BackColor="#00547E" />
</asp:GridView>




code behind file

     protected void gvProgram_RowDataBound(object sender, GridViewRowEventArgs e)
     {
         DataSet ds = new DataSet();
         Btech.Mode = "BindData";
         ds = objDal.Adm(Btech);
    
         if (e.Row.RowType == DataControlRowType.DataRow)
         {
             if (ds.Tables[0].Rows.Count > 0 && ds.Tables[1].Rows.Count > 0)
             {
                 DropDownList ddlProgram = (DropDownList)e.Row.FindControl("ddlProgram");
                 ddlProgram.Items.Clear();
                 ddlProgram.DataSource = ds.Tables[13];
                 ddlProgram.DataTextField = "Description";
                 ddlProgram.DataValueField = "CourseID";
                 ddlProgram.DataBind();
                 ddlProgram.Items.Insert(0, new ListItem("Select course", "0"));
    
    
                 DropDownList ddl_Location = (DropDownList)e.Row.FindControl("ddl_Location");
                 //ddlTeacherNames.Items.Clear();
                 ddl_Location.DataSource = ds.Tables[14];
                 ddl_Location.DataTextField = "CenterName";
                 ddl_Location.DataValueField = "CentreCode";
                 ddl_Location.DataBind();
                 ddl_Location.Items.Insert(0, new ListItem("Select Location", "0"));
             }
         }
    
     }
     
    ```
    protected void ddlProgram_SelectedIndexChanged(object sender, EventArgs e)
     {
    
     }

1

There are 1 best solutions below

0
Albert D. Kallal On

Ok, there are several things we have to deal with.

First, the GridView is loaded.

Then we have to load the 2 combo boxes, but ALSO setup the correct cascade values for the 2 combo boxes. And THEN we have to set the correct value of the combo box based on the row data source. So, in theory there are 3 steps here. And this step is somewhat backwards, since that 2nd combo box selection and value has to setup the correct values in the first combo box.

Then, after all above is done, then we need to setup the combo boxes to cascade correctly WHEN the user selects the first combo box, and cascade to the 2nd in that one GridRow.

Often, this will suggest that the 1st combo box is NOT bound to any data in the given row, but ONLY the 2nd combo box is to be bound to the given row data.

I don't have your sample data, but let's assume some people, and we select the city, and then the 2nd cascaded combo box is the hotel they selected.

So, first our GridView markup:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ID" 
    CssClass="table"
    Width="30%" OnRowDataBound="GridView1_RowDataBound">

    <Columns>
        <asp:BoundField DataField="Firstname" HeaderText="Firstname" />
        <asp:BoundField DataField="LastName" HeaderText="LastName"  />
        <asp:TemplateField HeaderText="Select Hotel City">
            <ItemTemplate>
                <asp:DropDownList ID="cboCity" runat="server" Width="120px"  Height="26px"
                    DataTextField = "City"
                    DataValueField = "City"
                    AutoPostback="true" 
                    OnSelectedIndexChanged="cboCity_SelectedIndexChanged"
                    > 
                </asp:DropDownList>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Select Hotel">
            <ItemTemplate>
                <asp:DropDownList ID="cboHotels" runat="server" Width="210px"  Height="26px"
                    DataValueField ="ID"
                    DataTextField ="HotelName">
                </asp:DropDownList>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

I will also point out that I don't bother with the GridView events, and I suggest you don't bother either. So, first the code to load the combo boxes.

    DataTable rstCity = new DataTable();
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadGrid();
    }

    void LoadGrid ()
    {
        // load up City list for combo box - all rows (scope = page)
        SqlCommand cmdSQL = new SqlCommand("SELECT City from City ORDER BY City");
        rstCity = MyRstP(cmdSQL);

        // load up the grid
        cmdSQL.CommandText = "SELECT * from People ORDER BY FirstName"; 
        GridView1.DataSource = MyRstP(cmdSQL);
        GridView1.DataBind();
    }

Ok, so above load the GridView. However, as noted, while we have 2 combo boxes (select city, then select a hotel in that given city list), ONLY the 2nd combo box selection need be saved.

So, in Row data bound, we have to not only load the 2 combo boxes, but correctly set the city choice, and then load hotels based on that hotel, and then select the Hotel.

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            DataRowView gData = (DataRowView)e.Row.DataItem; // get the row data
            // load the city combo box
            DropDownList cboCity = (DropDownList)e.Row.FindControl("cboCity");
            cboCity.DataSource = rstCity;
            cboCity.DataBind();
            // add blank row for city
            cboCity.Items.Insert(0, new ListItem("Select City", ""));

            // We have to check if a hotel been selected.

            SqlCommand cmdSQL = new SqlCommand();
            DropDownList cboHotels = (DropDownList)e.Row.FindControl("cboHotels");
            Debug.Print($"<{gData["Hotel_ID"].ToString()}>");
            if (gData["Hotel_ID"] != DBNull.Value) {
                cmdSQL = new SqlCommand("SELECT ID, City, HotelName FROM tblHotels WHERE ID = @ID");
                cmdSQL.Parameters.Add("@ID", SqlDbType.Int).Value = gData["Hotel_ID"];
                DataRow OneHotel = MyRstP(cmdSQL).Rows[0];

                // now load Hotel combo box - but cascade from above City cbo
                string strSQL = @"Select ID, HotelName From tblHotels WHERE City = @City " +
                                " ORDER BY HotelName";
                cmdSQL = new SqlCommand(strSQL);
                cmdSQL.Parameters.Add("@City", SqlDbType.NVarChar).Value = OneHotel["City"];

                DataTable rstHotels = MyRstP(cmdSQL);
                cboHotels.DataSource = rstHotels;
                cboHotels.DataBind();
                cboHotels.Items.Insert(0, new ListItem("Select Hotel", ""));
                // set hotels combo to current selected
                cboHotels.SelectedValue = gData["Hotel_id"].ToString();

                // set City combo box to current selected City
                cboCity.SelectedValue = OneHotel["City"].ToString();
            }
        }
    }

So, above sets up everything. Next up is the cascade of the city selection. So, note in above, the markup for the combo box is this:

 <asp:TemplateField HeaderText="Select Hotel City">
     <ItemTemplate>
         <asp:DropDownList ID="cboCity" runat="server" Width="120px"  Height="26px"
             DataTextField = "City"
             DataValueField = "City"
             AutoPostback="true" 
             OnSelectedIndexChanged="cboCity_SelectedIndexChanged"
             > 
         </asp:DropDownList>
     </ItemTemplate>
   

Note how the auto post back = true. And note the event setting for the combo box.

So, the city combo box changed event is this:

    protected void cboCity_SelectedIndexChanged(object sender, EventArgs e)
    {
        // city changed, so cascade Hotel cbo
        DropDownList cboCity = (DropDownList)sender;
        GridViewRow gRow = (GridViewRow)cboCity.NamingContainer;
        // filter hotels to current city
        string strCity = cboCity.SelectedItem.Text;
        DropDownList cboHotels = (DropDownList)gRow.FindControl("cboHotels");
        if (strCity != "Select City")
        {
            SqlCommand cmdSQL = new 
                SqlCommand(@"SELECT * from tblHotels WHERE City  = @City ORDER BY HotelName");
            cmdSQL.Parameters.Add("@City", SqlDbType.NVarChar).Value = strCity;                
            cboHotels.DataSource = MyRstP(cmdSQL);
            cboHotels.DataBind();
            cboHotels.Items.Insert(0, new ListItem("Select Hotel", ""));
        }
    }

And of course, after the user makes changes, then we need to save the changes. So, our save button is this:

    protected void cmdSave_Click(object sender, EventArgs e)
    {
        foreach(GridViewRow gRow in GridView1.Rows)
        {
            DropDownList cboHotel = (DropDownList)gRow.FindControl("cboHotels");
            if (cboHotel.SelectedIndex > 0) 
                rstGrid.Rows[gRow.RowIndex]["Hotel_id"] = cboHotel.SelectedItem.Value;
        }

        using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
        {
            string strSQL = "SELECT * FROM People ORDER BY FirstName,ID";
            using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
            {
                conn.Open();
                SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
                SqlCommandBuilder dau = new SqlCommandBuilder(da);
                da.Update(rstGrid);
            }
        }
    }

And the result is this:

enter image description here