Hi,

In my page I have a GridView in which I have an Item Template with a label and Edit Template with a DropDownList. Something like this:

<asp:GridView ID="MyGridView" runat="server" OnPageIndexChanging="MyGridView_PageIndexChanging" DataKeyNames="Id" OnRowEditing="MyGridView_RowEditing">
   <Columns>
      <asp:TemplateField HeaderText="Use" ItemStyle-Width="140px" ItemStyle-HorizontalAlign="Center">
         <ItemTemplate>
            <asp:Label ID="UseLabel" runat="server" Text='<%#Eval("ImageUse")%>' />
         </ItemTemplate>
         <EditItemTemplate>
            <asp:DropDownList ID="UseDropDownList" runat="server" OnDataBinding="UseDropDownList_DataBinding" />
         </EditItemTemplate>
      </asp:TemplateField>
   </Columns>
</asp:GridView>

However, in the method UseDropDownList_DataBinding the line

Dim UseDropDownList As DropDownList = ExclusiveHistoryGridView.FindControl("UseDropDownList")

always result nothing. With this, I can't Bind the DropDownList because it's not being found. How do I bind it then?

Thanks in advance for all replies!

Ana

Dani AI

Generated

The root cause is the GridView template naming container: controls placed inside an ItemTemplate/EditItemTemplate live in the row's naming container, not as direct children of the GridView. That explains why GridView.FindControl("...") returned Nothing for . Binding from inside the control's own DataBinding/DataBound event (casting sender) or binding per-row in the GridView RowDataBound event (as @Francis: suggested) is the correct pattern. See the framework docs for how FindControl and templated rows are scoped: Control.FindControl and GridView.RowDataBound.

A practical, reliable approach is to bind the DropDownList inside its DataBinding handler so the sender is the list and the row's DataItem is available for selecting the current value:

Protected Sub UseDropDownList_DataBinding(sender As Object, e As EventArgs)
    Dim ddl As DropDownList = CType(sender, DropDownList)
    Dim row As GridViewRow = CType(ddl.NamingContainer, GridViewRow)
    Dim currentValue = DataBinder.Eval(row.DataItem, "ImageUse")
    ddl.DataSource = GetLookupTable()    ' supply the lookup table
    ddl.DataBind()
    If currentValue IsNot Nothing Then ddl.SelectedValue = currentValue.ToString()
End Sub

Alternatives and cautions: the RowDataBound route (find the DDL with e.Row.FindControl) works well for per-row logic and was described by @Francis:. Declarative binding inside the template (the pattern mentioned by ) is also valid for simple lookups and automatic two-way binding. Avoid rebinding dropdowns on every postback (selection will be lost); bind only during the appropriate lifecycle phase. For updates, retrieve the chosen value from the edited row (use e.Row.FindControl or CType(ddl.NamingContainer, GridViewRow) inside update handlers). If the datasource is an ADO.NET DataTable as noted, it can be used as the lookup source.

Recommended Answers

All 4 Replies

AFAIK the reason you aren't finding the DropDownLists is that each DDL get its own unique ID like; DropDownList123555.

You can get the unique IDs by using the GridView's RowDataBound event:

protected void MyGridView_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            DropDownList DDL = (DropDownList)e.Row.FindControl("UseDropDownList");

            DDL.DataSource = whatever datasource you want;
            
            string uniqueID = DDL.UniqueID; //This is what you need to find the DDL later on.
            
            int rowIndex = int.Parse(e.Row.RowIndex.ToString());
        } 
    }

It shouldn't be too hard to re-write the code to VB :).

Regards

Francis

Hi,

To Bind the Dropdown list.. First Write a Function in .vb page (say RetMyTable) which returns a DataTable and Your Edit Item Template should look like this...:

<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" Runat="server"     
DataSource='<%#RetMyTable() %>'
DataTextField="MyFieldName" DataValueField="MyFieldName"
SelectedValue='<%# Bind("MyFieldName") %>' />                        
</EditItemTemplate>

Regards
Veena

you used ado.net with bind the control...

I think I didn't express my question clearly. I know how to bind a DropDownList in the code behind. The problem I was having, however, was that, in the ItemTemplate (when the data is only being displayed to the user) I have a Label where the Text is retrieved from the database: Text='<%#Eval("ImageUse")%>'
When the User clicks on Edit Button, this label should be replaced by a DropDownList, which call the myDropDownList_DataBinding. In Protected Sub myDropDownList_DataBound (...) I had: Dim ddl as DropDownList = myGridView.FindControl("myDropDownList"). The problem was: myGridView.FindControl("myDropDownList") = Nothing and this is why I couldn't bind the DropDownList.
The solution was, instead of using myGridView.FindControl("myDropDownList"), use this: Dim myDropDownList as DropDownList = sender (actually, the sender is the DropDownList...) and bind the ddl.

Thanks for all the replies.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.