Repeater中的下拉列表:如何处理SelectedIndexChange事件并获取DataItem?

7

我正在在Repeater中放置一个带有AutoPostBack的DropDownList。
(列表项在Repeater的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)
    {
    //此函数从未被调用
    }

  2. 那么在我让它正常工作后,我该如何获取 DataItem 呢?

我这样做是错的吗?

非常感谢。

5个回答

14

为了在PostBack时注册下拉列表,请添加以下代码:

 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...
希望这能帮到你。

非常感谢!那么我该如何获取DropDownList所属的DataItem呢? - Aximili
1
DataItem仅在ItemCreated和ItemDataBound方法中可用。我认为你需要向重复器添加一些控件,以便引用要检索的项。 - jmaglio
为什么不使用 OnSelectedIndexChanged="ddlSize_SelectedIndexChanged" - toddmo

2

我认为你发布的代码片段没有问题。

当IsPostBack为true且在PageLoad期间,你是否调用了repeater的DataBind()函数? 如果是这样,你将会失去DDLs上的SelectedIndexChanged事件。

你应该存储ID,例如在value或HiddenField中,在postback处理期间加载特定的DataItems(ListView有DataKey用于此目的)。

作为一般指导原则:

  • 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");
    }
    

2
这里的答案很好,但缺少一个关键检查。如果你想知道为什么会出现对象引用未设置为对象实例的错误,重要的是要注意,重复器将首先创建其标题,然后才是任何数据项。
进行此检查:
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;
     }
}

1
如果你只想触发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.
    }

就是这样。现在你的事件将被调用。


-1

试试这个

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接