Search code examples
c#repeatercode-behindhtml-select

dropdownlist in header template of repeater not working


I have set up what I think is the correct markup and code behind to put a dropdownlist in the header template of a repeater, yet for some reason, it's not working correctly. Initially I see the dropdown list, but when I make a selection in the list, the OnSelectedIndexChanged event does not seem to trigger use of the method added to handle it and I can't figure out what I'm missing, as I thought this was a straightforward thing.

Here are the essentials of the markup:

<asp:Repeater ID="repNewsItems" runat="server">
<HeaderTemplate>
        <asp:DropDownList ID="ddDateSortCategories" runat="server" Width="200" AutoPostBack="true" OnSelectedIndexChanged="ddDateSortCategories_SelectedIndexChanged1" CssClass="mergersDropDown">
            <asp:ListItem Selected="True" Text="Most Recent" Value="newest"></asp:ListItem>
            <asp:ListItem Text="Oldest" Value="oldest"></asp:ListItem>
        </asp:DropDownList>
</HeaderTemplate>

<ItemTemplate>
    // other stuff

And here are the guts of the code behind:

    [MacroParameter(MacroParameterType.Number)]
    public int PageId { get; set; }

    public string _category = "";

    protected void Page_Load(object sender, EventArgs e)
    {
        if (repNewsItems == null) return;

        _category = Request.QueryString["category"];

        repNewsItems.ItemDataBound += new RepeaterItemEventHandler(repNewsItems_ItemDataBound);

        repNewsItems.DataSource = (string.IsNullOrEmpty(NewsNodeIds))
                                        ? GetNewsItemsForYear(NewsYearToDisplay, _category)
                                        : DaNews;
        repNewsItems.DataBind();
    }

    protected void ddDateSortCategories_SelectedIndexChanged1(object sender, EventArgs e)
    {
        DropDownList ddl = (DropDownList)(sender);
        Response.Redirect(umbraco.library.NiceUrl(PageId) + "?category=" + Server.UrlEncode(ddl.SelectedValue.ToString()));
    }

    void repNewsItems_ItemDataBound(object sender, RepeaterItemEventArgs e)
    { 
        if (e.Item.ItemType == ListItemType.Header)
        {
            DropDownList ddl = (DropDownList)e.Item.FindControl("ddDateSortCategories");
            if (!IsPostBack)
            {
                if (ddl != null)
                {
                    ddl.DataSource = GetNewsItemsForYear(DocumentTypes.NewsItem.GetMostRecentYear(NewsCategoryToDisplay).ToString(), _category);
                    ddl.DataBind();
                }
            }
            if (!String.IsNullOrEmpty((Request.QueryString["category"]))) ddl.Text = Request.QueryString["category"];
        }
        // other stuff
     }

Solution

  • I found two issues with the code above. First, I was mistakenly binding my list items to my dropdownlist, which I meant to have hard-coded list items that wouldn't change. That didn't fix my main issue, though. What did was that I was forgetting to wrap these:

    repNewsItems.ItemDataBound += new RepeaterItemEventHandler(repNewsItems_ItemDataBound);
    repNewsItems.DataSource = (string.IsNullOrEmpty(NewsNodeIds))
                                        ? GetNewsItemsForYear(NewsYearToDisplay, _category)
                                        : DaNews;
    repNewsItems.DataBind();
    

    in a

    if (!IsPostBack) {} 
    

    conditional statement. That meant that each time the postback event fired, it would enter the Page_Load method, rebind the entire repeater in its initial state and never let it pass through to my SelectedIndexChanged event handler ddDateSortCategories_SelectedIndexChanged1.