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" />
...
Во-первых, эта функция даже не была активирована
protected void ddlSize_SelectedIndexChanged(object sender, EventArgs e)
{
//This function is never called
}
Как мне получить 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;