DropDownList внутри Repeater: Как обработать SelectedIndexChange и получить DataItem?

Я помещаю DropDownList с AutoPostBack внутри повторителя.
(ListItems заполняются на 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. Во-первых, эта функция даже не была активирована

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

  2. Как мне получить DataItem после того, как он заработает?

Я делаю это неправильно?

Заранее спасибо.

5 ответов

Решение

Чтобы зарегистрировать выпадающий список для обратной передачи, добавьте следующий код:

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

И в вашем файле ASPX, добавьте это к вашей разметке повторителя:

OnItemCreated="RepeaterItemCreated"

Затем в вашей функции ddlSize_SelectedIndexChanged вы можете получить доступ к родительскому элементу управления следующим образом:

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

Надеюсь это поможет.

Ответ здесь хороший, но пропущен важный чек. Если вам интересно, почему вы получаете ссылку на объект, а не экземпляр ошибки объекта, важно отметить, что повторитель сначала создаст свой HEADER перед любыми элементами данных.

Выполните эту проверку:

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;
     }
}

Я не вижу проблем с той частью кода, которую вы разместили.

Вы вызываете DataBind() на своем повторителе, когда IsPostBack имеет значение true, и во время PageLoad? Если это так, вы потеряете SelectedIndexChanged на вас DDL

Вы должны хранить идентификаторы, например, в значениях или HiddenField, чтобы загружать определенные DataItems во время обратной обработки (ListView имеет DataKey для этой цели)

Как общее руководство:

  • часто лучше вызывать DataBind() во время PreRender
  • Вы не должны вызывать DataBind() во время обратной передачи, если базовые данные не изменились
  • если вы выполните два указанных выше пункта, вы не сможете использовать DataItems в item_created (поскольку ваши DataItems будут доступны только при вызове 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");
    }
    

Если вы просто хотите запустить OnSelectedIndexChanged, это должно выглядеть так:

Page.aspx - Источник

<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 - код позади

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

И это все. Ваше событие будет называться сейчас.

Попробуй это

DropDownList drp = sender as DropDownList;
    int RepeaterItemIndex = ((RepeaterItem)drp.NamingContainer).ItemIndex;
Другие вопросы по тегам