How to populate DropDownList in GridView EditItemTemplate depending on other column values

GISmatters picture GISmatters · May 17, 2013 · Viewed 8.7k times · Source

When editing a row in a GridView, I need a DropDownList whose list of available values depends on other column(s) in the row (let's just say the "type" of the record for now); that is, different options will be listed depending on which row is being edited.

I got it working after a fashion by adding an otherwise-unneeded DataKeyName to the GridView, but this is causing me grief elsewhere and anyway it feels too circuitous, so I'm looking for a better way. Here's how I'm currently doing it:

In .aspx file:

<asp:GridView ID="gvDct" ... DataKeyNames="dctId,dctType" ... >
  ...
  <asp:TemplateField>
    ...
    <EditItemTemplate>
      <asp:DropDownList ID="ddlDctParent" runat="server" 
             DataSourceId="sdsDctParent" 
             DataValueField="dctId" DataTextField="dctFullPath" 
             SelectedValue='<%# Bind("dctParentId") %>' 
             ... >
      </asp:DropDownList>
      <asp:SqlDataSource ID="sdsDctParent" runat="server" 
             ConnectionString="<%$ ConnectionStrings:ConnectionString %>" 
             OnSelecting="sdsDctParent_Selecting" 
             SelectCommand="SELECT dctId, dctFullPath FROM lkpDocCatAndType 
                            WHERE dctType=@dctType">
        <SelectParameters>
          <asp:Parameter Name="dctType" />
        </SelectParameters>
      </asp:SqlDataSource>
    </EditItemTemplate>
  </asp:TemplateField>
  ...
</asp:GridView>

I wanted the SelectParameter to be a ControlParameter with ControlID="gvDct" and PropertyName="SelectedDataKey.Values[dctType]", but for unknown reasons that didn't work (the parameter values were null), so I added this bit to the .vb code-behind file to populate the row-specific parameter for the data source of the DropDownList:

Protected Sub sdsDctParent_Selecting(ByVal sender As Object, _
          ByVal e As System.Web.UI.WebControls.SqlDataSourceSelectingEventArgs)
  e.Command.Parameters(0).Value = gvDct.DataKeys(gvDct.EditIndex).Item(1)
End Sub

So, when I start editing a row in the GridView, the DropDownList is bound, which causes the SqlDataSource SelectCommand to execute, which fires the OnSelecting code where I provide the parameter value from the row being edited (EditIndex) so that I get the appropriate population of values in the DropDownList.

Is there a "better" way? The most important aspect for me is to avoid adding the DataKeyName, because that is causing me a too-many-parameters problem on the stored procedure I'm using to delete a row from the GridView.

Answer

Satinder singh picture Satinder singh · May 18, 2013

You should use Gridview RowDataBound where you can fetch the valueID a later on you can populate your Dropdownlist also add a label/hidden field whose value you want to populate DropdownList
Sry for writing code in c#.

You can try something like this

protected void gvDct_RowDataBound(object sender, GridViewRowEventArgs e)
{
 if (e.Row.RowType == DataControlRowType.DataRow)
  {
   if ((e.Row.RowState & DataControlRowState.Edit) > 0)
     {
      Label  lblValue = (Label)e.Row.FindControl("YourLableID")
      DropDownList ddList= (DropDownList)e.Row.FindControl("ddlDctParent");
      //bind dropdownlist
      DataTable dt = con.GetData("Select Query where YourColumn='"+lblValue.text+"'");
      ddList.DataSource = dt;
      ddList.DataTextField = "dctFullPath";
      ddList.DataValueField = "dctId";
      ddList.DataBind();

      DataRowView dr = e.Row.DataItem as DataRowView;
      ddList.SelectedValue = dr["dctId"].ToString();
     }
   }
 }