Search code examples
c#asp.netgridviewselectedvalueedititemtemplate

Gridview EditItemTemplate DropDownList Get SelectedValue


In my Gridview I have the following template field:

<asp:TemplateField HeaderText="Dept Code" SortExpression="DeptCode">
    <ItemTemplate>
        <%# Eval("DeptCode") %>
    </ItemTemplate>
    <EditItemTemplate>
        <asp:DropDownList ID="ddlDeptCode" runat="server" 
            SelectedValue='<%# Eval("DeptCode") %>' 
            DataSource='<%# GetAllDepartments() %>' 
            DataTextField="DeptCode" 
            DataValueField="DeptCode" />
    </EditItemTemplate>
</asp:TemplateField> 

This works great when I click Edit on a row it populates the DropDownList with all values and selects the correct value for that row.

However, when I try to update the row: OnRowUpdating="UpdateRow"

protected void UpdateRow(object sender, GridViewUpdateEventArgs e)
{
    GridViewRow row = UserGV.Rows[e.RowIndex];
    DropDownList ddl = row.FindControl("ddlDeptCode") as DropDownList;
    string deptCode = ddl.SelectedValue;
}

It finds the DropDownList control but the SelectedValue is always an empty string.
I need access to the selected value to save to the database.

Any ideas as to how I can get the SelectedValue of a DropDownList in a Gridview in code behind?

Edit:
You can also populate the DropDownList and SelectedValue from the code behind:

protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
     if (e.Row.RowType == DataControlRowType.DataRow)
     {
        if ((e.Row.RowState & DataControlRowState.Edit) > 0)
        {
           var deptMgr = new DepartmentMgr();
           List<Department> departments = deptMgr.GetAllDepartments();
           DropDownList ddList = (DropDownList)e.Row.FindControl("ddlDeptCode");
           ddList.DataSource = departments;
           ddList.DataTextField = "DeptCode";
           ddList.DataValueField = "DeptCode";
           ddList.DataBind();

           string userDeptCode = DataBinder.Eval(e.Row.DataItem, "DeptCode").ToString();
           ddList.SelectedItem.Text = userDeptCode;
           ddList.SelectedValue = userDeptCode;
       }
    }
}

Solution

  • I was using a bit of a hack to get a second header for the table title when binding the gridview:

    GridViewRow row = new GridViewRow(0, -1, DataControlRowType.Header, DataControlRowState.Normal);
    TableCell th = new TableHeaderCell();
    th.HorizontalAlign = HorizontalAlign.Center;
    th.ColumnSpan = UserGV.Columns.Count;
    th.BackColor = Color.SteelBlue;
    th.ForeColor = Color.White;
    th.Font.Bold = true;
    th.Text = "Manage Users";
    row.Cells.Add(th);
    InnerTable.Rows.AddAt(0, row);
    

    I don't completely understand how this was interfering with getting the SelectedValue of a DropDownList control but as soon as I commented that out it started working.

    For those interested I got the second header working with this using a different approach:

    In the .aspx file I added this to the Gridview:

    OnRowCreated="CreateRow"
    

    And in the code behind I added the following method:

    protected void CreateRow(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.Header)
        {           
            GridView gridView = (GridView)sender;
            GridViewRow row = new GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Normal);
            TableCell th = new TableHeaderCell();
            th.HorizontalAlign = HorizontalAlign.Center;
            th.ColumnSpan = UserGV.Columns.Count;
            th.ForeColor = Color.White;
            th.BackColor = Color.SteelBlue;
            th.Font.Bold = true;
            th.Text = "Manage Users";
            row.Cells.Add(th);
    
            gridView.Controls[0].Controls.AddAt(0, row);
        }
    }
    

    Everything is working correctly now.