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

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

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

  2. как я тогда получу DataItem после того, как я заставлю его работать?

я делаю это неправильно способ?

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

5 ответов


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

 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...

надеюсь, что это помогает.


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

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

вы должны хранить идентификаторы, например, в значениях или 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, вот как это должно выглядеть:

страница.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>

страница.аспн.cs-Code-behind

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

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


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

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

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

попробуй такое

DropDownList drp = sender as DropDownList;
    int RepeaterItemIndex = ((RepeaterItem)drp.NamingContainer).ItemIndex;