How do you bind a DropDownList in a GridView in the EditItemTemplate Field?

42,336

Solution 1

Ok, I guess I'm just dumb. I figured it out.

In the RowDataBound event, simply add the following conditional:

if (myGridView.EditIndex == e.Row.RowIndex)
{
     //do work
}

Solution 2

Thanks to Saurabh Tripathi,

The solution you provided worked for me. In gridView_RowDataBound() event use.

if(gridView.EditIndex == e.Row.RowIndex && e.Row.RowType == DataControlRowType.DataRow)
{
    // FindControl
    // And populate it
}

If anyone is stuck with the same issue, then try this out.

Cheers.

Solution 3

I had the same issue, but this fix (Jason's, which is adding the conditional to the handler) didn't work for me; the Edit row never was databound, so that condition never evaluated to true. RowDataBound was simply never called with the same RowIndex as the GridView.EditIndex. My setup is a little different, though, in that instead of binding the dropdown programmatically I have it bound to an ObjectDataSource on the page. The dropdown still has to be bound separately per row, though, because its possible values depend on other information in the row. So the ObjectDataSource has a SessionParameter, and I make sure to set the appropriate session variable when needed for binding.

<asp:ObjectDataSource ID="objInfo" runat="server" SelectMethod="GetData" TypeName="MyTypeName">
<SelectParameters>
    <asp:SessionParameter Name="MyID" SessionField="MID" Type="Int32" />
</SelectParameters>

And the dropdown in the relevant row:

<asp:TemplateField HeaderText="My Info" SortExpression="MyInfo">
        <EditItemTemplate>
            <asp:DropDownList ID="ddlEditMyInfo" runat="server" DataSourceID="objInfo" DataTextField="MyInfo" DataValueField="MyInfoID" SelectedValue='<%#Bind("ID") %>' />
        </EditItemTemplate>
        <ItemTemplate>
            <span><%#Eval("MyInfo") %></span>
        </ItemTemplate>
    </asp:TemplateField>

What I ended up doing was not using a CommandField in the GridView to generate my edit, delete, update and cancel buttons; I did it on my own with a TemplateField, and by setting the CommandNames appropriately, I was able to trigger the built-in edit/delete/update/cancel actions on the GridView. For the Edit button, I made the CommandArgument the information I needed to bind the dropdown, instead of the row's PK like it would usually be. This luckily did not prevent the GridView from editing the appropriate row.

<asp:TemplateField>
        <ItemTemplate>
            <asp:ImageButton ID="ibtnDelete" runat="server" ImageUrl="~/images/delete.gif" AlternateText="Delete" CommandArgument='<%#Eval("UniqueID") %>' CommandName="Delete" />
            <asp:ImageButton ID="ibtnEdit" runat="server" ImageUrl="~/images/edit.gif" AlternateText="Edit" CommandArgument='<%#Eval("MyID") %>' CommandName="Edit" />
        </ItemTemplate>
        <EditItemTemplate>
            <asp:ImageButton ID="ibtnUpdate" runat="server" ImageUrl="~/images/update.gif" AlternateText="Update" CommandArgument='<%#Eval("UniqueID") %>' CommandName="Update" />
            <asp:ImageButton ID="ibtnCancel" runat="server" ImageUrl="~/images/cancel.gif" AlternateText="Cancel" CommandName="Cancel" />
        </EditItemTemplate>
    </asp:TemplateField>

And in the RowCommand handler:

void grdOverrides_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            if (e.CommandName == "Edit")
                Session["MID"] = Int32.Parse(e.CommandArgument.ToString());
        }

The RowCommand, of course, happens before the row goes into edit mode and thus before the dropdown databinds. So everything works. It's a little bit of a hack, but I'd spent enough time trying to figure out why the edit row wasn't being databound already.

Share:
42,336
Ricardo Gomes
Author by

Ricardo Gomes

I &lt;3 Web8 (HTML5 + CSS3) Monitor Stack Exchange questions with Google Chrome using StackStalker!

Updated on February 04, 2020

Comments

  • Ricardo Gomes
    Ricardo Gomes about 4 years

    Here's my code in a gridview that is bound at runtime:

    ...
    <asp:templatefield>
        <edititemtemplate>
            <asp:dropdownlist runat="server" id="ddgvOpp" />
        </edititemtemplate>
        <itemtemplate>
            <%# Eval("opponent.name") %>
        </itemtemplate>
    </asp:templatefield>
    ...
    

    I want to bind the dropdownlist "ddgvOpp" but i don't know how. I should, but I don't. Here's what I have, but I keep getting an "Object reference" error, which makes sense:

    protected void gvResults_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow) //skip header row
        {
            DropDownList ddOpp = (DropDownList)e.Row.Cells[5].FindControl("ddgvOpp");
            BindOpponentDD(ddOpp);
        }
    }
    

    Where BindOpponentDD() is just where the DropDownList gets populated. Am I not doing this in the right event? If not, which do I need to put it in?

    Thanks so much in advance...

  • quillbreaker
    quillbreaker almost 15 years
    I think you also don't need (e.Row.RowType == DataControlRowType.DataRow) unless you've hacked editable header rows in somehow.
  • Ricardo Gomes
    Ricardo Gomes almost 15 years
    no you do because it starts w/the header row and works its way down. you get an error if you don't do this, or it just doesn't function.
  • Emad Mokhtar
    Emad Mokhtar over 11 years
    Or you can check if the row is in the edit mode by this if(e.RowState && DataControlRowState.Edit) > 0 {}