DropDownList inside Repeater: How to handle SelectedIndexChange and get DataItem?

18,749

Solution 1

To register the dropdownlist for postback, add the following code:

 protected virtual void RepeaterItemCreated(object sender, RepeaterItemEventArgs e)
    {
        DropDownList MyList = (DropDownList)e.Item.FindControl("ddlSize");
        MyList.SelectedIndexChanged += ddlSize_SelectedIndexChanged;
    }

And in your aspx file, add this to your repeater markup:

OnItemCreated="RepeaterItemCreated"

Then, in your ddlSize_SelectedIndexChanged function, you can access the parent control like this:

   DropDownList d = (DropDownList)sender;
   (RepeaterItem) d.Parent...

Hope this helps.

Solution 2

I see no problem with the portion of code you posted.

Do you call DataBind() on your repeater when IsPostBack is true, and during PageLoad ? If so, you will lose the SelectedIndexChanged on you DDLs

You should store IDs, for example in values or HiddenField, to load specific DataItems during postback processing (ListView has DataKey for this purpose)

As a general guideline :

  • it's often better to call DataBind() during PreRender
  • you should not call DataBind() during postback if underlying data hasn't changed
  • if you do the two points above, you will not be able to use DataItems in item_created (as your DataItems will be available only when you call DataBind())

    protected void Page_Load(object sender, EventArgs e)
    {
        this.PreRender += new EventHandler(test_PreRender);
    }
    
    void test_PreRender(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            rptWishlist.DataSource = new int[] { 1, 2, 3, 4 };
            rptWishlist.DataBind();
        }
    }
    
    protected void rptWishlist_ItemCommand(object sender, RepeaterCommandEventArgs e)
    {
        //Command Code Here
    }
    
    protected void rptWishlist_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        var i = (int) e.Item.DataItem;
        var ddl = (DropDownList)e.Item.FindControl("ddlSize");
        for(int j=1; j<=i;j++)
        {
            ddl.Items.Add(new ListItem(){Text = j.ToString()});
    
        }
    }
    
    protected void ddlSize_SelectedIndexChanged(object sender, EventArgs e)
    {
        Response.Write("changed");
    }
    

Solution 3

The answer here is good but missing a crucial check. If you're wondering why you're getting object reference not set to an instance of an object errors, it's important to note that the repeater will create its HEADER first before any data items.

Perform this check:

protected void rptProjects_ItemCreated(object sender, RepeaterItemEventArgs e)
{
     if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
     {
           ((DropDownList)e.Item.FindControl("yourcontrol")).SelectedIndexChanged += ddlAction_SelectedIndexChanged;
     }
}

Solution 4

If you just want to fire the OnSelectedIndexChanged, this is how it should look:

Page.aspx - Source

<FooterTemplate>
    <asp:DropDownList ID="ddlOptions"
             runat="server" 
             AutoPostBack="true" 
             onselectedindexchanged="ddlOptions_SelectedIndexChanged">
        <asp:ListItem>Option1</asp:ListItem>
        <asp:ListItem>Option2</asp:ListItem>
    </asp:DropDownList>
</FooterTemplate>

Page.aspx.cs - Code-behind

protected void ddlOptions_SelectedIndexChanged(object sender, EventArgs e)
    {
        //Event Code here.
    }

And that's it. Your event will be called now.

Share:
18,749
Emiel Bruijntjes
Author by

Emiel Bruijntjes

Updated on June 25, 2022

Comments

  • Emiel Bruijntjes
    Emiel Bruijntjes almost 2 years

    I am putting a DropDownList with AutoPostBack inside a Repeater.
    (The ListItems are populated on the repeater's ItemDataBound)

    <asp:Repeater ID="rptWishlist" OnItemCommand="rptWishlist_ItemCommand" onItemDataBound="rptWishlist_ItemDataBound" runat="server">
      <ItemTemplate>
        ...
        <asp:DropDownList ID="ddlSize" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddlSize_SelectedIndexChanged" />
        ...
    
    1. Firstly, this function was not even fired on post back

      protected void ddlSize_SelectedIndexChanged(object sender, EventArgs e)
      {
      //This function is never called
      }

    2. How would I then get the DataItem after I get it working?

    Am I doing this the wrong way?

    Thank you in advance.

  • Emiel Bruijntjes
    Emiel Bruijntjes about 12 years
    Thanks a lot! Then how do I get the DataItem the DropDownList belong to?
  • jmaglio
    jmaglio about 12 years
    DataItem is only available in the ItemCreated and ItemDataBound methods. I think what you'll have to do is add some control to the repeater that you can use to reference the item you want to retrieve.
  • toddmo
    toddmo about 8 years
    Why not OnSelectedIndexChanged="ddlSize_SelectedIndexChanged"?