面板列表中动态创建的下拉列表不允许进行事件处理



我正在尝试创建一个UI,用于创建可以动态填充的行。

我现在可以将一个面板添加到我的列表中,该列表包含一个DropDownList并有一个关联的Remove按钮。

Remove按钮有一个OnClick事件绑定,允许我删除该特定面板。

我在尝试将SelectedIndexChanged事件处理程序绑定到我的DropDownList时遇到问题,但没有。

我怀疑这与我在每次Postback后如何重新创建控件有关。

我并没有要求或期待一个直截了当的"在代码中添加或更改此项"。我真的很想了解我错在哪里,很抱歉问了这么多!:s

protected void Page_Load(object sender, EventArgs e)
{
    //Showing this for the the poster that asked.
    if (!IsPostBack)
    {
        GetClustersFromDB(user);
        BindGrid();
        BindState();            
    }
    if (Session["persistControls"] != null)
    {
        persistControls = (List<Panel>)Session["persistControls"];
        int count = 0;
        foreach (Panel dynamicControl in persistControls)
        {
            DropDownList list = new DropDownList();
            list.ID = "list" + count;
            list.SelectedIndexChanged += new EventHandler(list_SelectedIndexChanged);
            list.AutoPostBack = true;
            list.Items.Add(new ListItem("", "0"));
            list.Items.Add(new ListItem("Title", "1"));
            dynamicControl.ID = "panel" + count;
            Button btnRemove = new Button();
            btnRemove.Click += new EventHandler(btnDelete_Click);
            btnRemove.Text = "Remove";
            btnRemove.CommandArgument = count.ToString();             
            myPlaceholder.Controls.Add(dynamicControl);
            myPlaceholder.Controls.Add(btnRemove);
            count++;
        }
    }
}
protected void btnAdd_Click(object sender, EventArgs e)
{
    try
    {
        DropDownList list = new DropDownList();
        list.SelectedIndexChanged += new EventHandler(list_SelectedIndexChanged);
        list.AutoPostBack = true;
        list.Items.Add(new ListItem("", "0"));
        list.Items.Add(new ListItem("Title", "1"));
        Panel panelContainer = new Panel();
        panelContainer.ID = "panel" + persistControls.Count;
        panelContainer.Controls.Add(list);
        Button btnRemove = new Button();
        btnRemove.Click += new EventHandler(btnDelete_Click);
        btnRemove.Text = "Remove";
        btnRemove.CommandArgument = persistControls.Count.ToString();
        myPlaceholder.Controls.Add(panelContainer); // Pushes the Panel to the page.
        persistControls.Add(panelContainer);// Adds our Panel to the Control list
        myPlaceholder.Controls.Add(btnRemove); // Pushes our Button to the page.
        Session["persistControls"] = persistControls; // put it in the session
    }
    catch
    {
        throw;
    }
}
protected void btnDelete_Click(object sender, EventArgs e)
{
    try
    {
        int deleteThisOne = int.Parse(((Button)sender).CommandArgument);
        persistControls.Remove(persistControls[deleteThisOne]);
        Session["persistControls"] = persistControls;          
        Response.Redirect(Request.Url.ToString());
    }
    catch
    {
        throw;
    }
}
protected void list_SelectedIndexChanged(object sender, EventArgs e)
{
    throw new NotImplementedException();
}
//aspx File Snippets
<asp:Button ID="btnAdd" runat="server" Text="Add Control" onclick="btnAdd_Click" />
<asp:Button ID="btnClear" runat="server" Text="Reset" onclick="btnClear_Click"/>
<asp:PlaceHolder ID="myPlaceholder" runat="server"></asp:PlaceHolder>

像这样维护控件真的很痛苦。你可以尝试另一种方法:

  1. 创建一个(小)类,用于封装要在每个面板中显示的数据
  2. 在会话中维护这些对象的List
  3. 使用<asp:Repeater>通过将其绑定到列表的数据来显示项目
  4. 在中继器的ItemTemplate中,您可以写出可以包含<asp:DropDownList><asp:Panel>。使用下拉列表的ItemCommand属性将其绑定到服务器端事件处理程序。类似地,您可以在模板中放置一个<asp:Button>,并将其ItemCommand属性绑定到另一个服务器端事件处理程序
  5. 当您单击"添加"时,您将回发到服务器,添加到您的列表,将其保存在会话中,然后重新绑定中继器
  6. 当您单击删除时,您将回发到服务器,从列表中删除项目,将其保存在会话中,然后重新绑定中继器

通过这种方式,ASP.Net可以为您处理所有控件的创建。然而,如果你真的想自己做这一切,那么这篇无限循环博客文章是必读的。

我认为这行不通。如果您在PageLoad事件中创建下拉列表,则视图状态将永远不会绑定到它,并且您永远不会看到用户选择的选项。

您应该创建控件OnInit,然后当PostBack发生时,ViewState数据将绑定到控件,您将能够访问它。

最新更新