5

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;
       }
    }
}
Baxter
  • 5,633
  • 24
  • 69
  • 105
  • Have you tried like this in "UpdateRow" event. **DropDownList ddl = ((DropDownList)UserGV.Rows[e.RowIndex].Cells[1].Controls[1]).SelectedValue; string deptCode = ddl.SelectedValue;** – Krishnraj Rana Apr 08 '14 at 19:37
  • I tried: string deptCode = ((DropDownList)UserGV.Rows[e.RowIndex].Cells[2].Controls[1]).SelectedValue; Like the method I used above it finds the control but returns an empty string for the SelectedValue. – Baxter Apr 08 '14 at 19:49
  • 2
    are you filling the dropdownlist from the same gridview table or another table? – jack Apr 08 '14 at 20:07
  • @BlackBaron In the code above you can see I am filling the DropDownList in the EditItemTemplate by setting the DataSource to a method in the code behind that returns a List. If I understand your question correctly I would say the same Gridview table as I only have the one GridView. – Baxter Apr 08 '14 at 20:14
  • 1
    I see, because I created a simple database with xml and created two tables then tried exactly your code and it's working fine and showing values correctly, so I'm not sure what's the problem but I'll upload the simple project I made maybe you could figure it out then. – jack Apr 08 '14 at 20:17
  • @BlackBaron That would be great. When I click edit it is correctly populating the DropDownList and setting it to the correct SelectedValue. I can find the DropDownList control in the code behind OnRowUpdating method but its SelectedValue is set to "" and SelectedIndex = -1 – Baxter Apr 08 '14 at 20:24
  • 1
    I still have doubts that your problem will be in database values not in the design and access of dropdownlist, anyway please download the sample from here: https://docs.google.com/file/d/0B5Xsv2VzgUv0aHlmaXVrRmVydUE/edit I hope it help you. – jack Apr 08 '14 at 20:47
  • @BlackBaron Thanks for the code. That is exactly what I am doing except I have some additional code in my bind method to create a second header on the GridView for the table name. When I comment that out the code works. I'll post the second header code in my question. – Baxter Apr 08 '14 at 21:08
  • 1
    ok then waiting for the update. – jack Apr 08 '14 at 21:18
  • @BlackBaron Update complete. I will just need to find some alternative way to set a second header on the GridView. – Baxter Apr 08 '14 at 21:20
  • 1
    yeah it's really weird but good that you know the issue now, as for the alternative way of adding a second header, I'm already using this method here http://www.codeproject.com/Articles/249155/Rows-and-Columns-Merging-in-ASP-NET-GridView-Contr ,just copy the RowCreated & AddMergedCell method and modify them to suite your needs. I gotta go now but I hope you could solve this, keep it up mate. – jack Apr 08 '14 at 21:36

2 Answers2

2

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.

Baxter
  • 5,633
  • 24
  • 69
  • 105
  • 1
    Not sure this will be relevant to someone who visits this thread in the future but I was having the problem of the SelectedIndex in dropdownlist (ddl) of GridView (templatefield) was reverting to first index (losing database value/selectedindex)when Edit mode was clicked. @Baxter 's EDIT comment/example code in his question helped me realize that I set the SelectedIndex before ddl datatbind when it should be set after ddl DataBind. I spent days trying to figure this out! – Doreen Jun 03 '19 at 17:20
1

In the edit template, set the selectedvalue from the data bindings, then you will get the correct selected value instead of a null.

 SelectedValue='<%# Bind("DeptCode") %>'
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
tookay
  • 11
  • 1