如何添加/删除动态创建的用户控件

时间:2013-01-31 21:26:41

标签: c# asp.net dynamic user-controls webforms

所以我试图动态地添加和删除页面上的用户控件,详细说明我在网上找到的一个示例,该示例显示了如何动态添加用户控件。但我似乎无法让删除工作正常。我遵循的程序大致是......

  • 在主页面中,单击添加按钮时,我创建了一个用户控件并将其deleteBtnClk事件实例分配给方法deleteBtn_Click(object sender, EventArgs e),我将其传递给方法ucSimpleControl_deleteBtnClk来自后面的主页代码

    protected void btnAddControl_Click(object sender, EventArgs e)
    {
        // Create instance of the UserControl SimpleControl
        usercontrols.SimpleControl ucSimpleControl =
          LoadControl("~/usercontrols/SimpleControl.ascx")
          as usercontrols.SimpleControl;
    

    ... ... ...

        ucSimpleControl.deleteBtnClk +=
            new usercontrols.deleteBtn_Click(ucSimpleControl_deleteBtnClk);
    

我也这样做是代码隐藏方法CreateUserControl(string controlID),它是从OnPreInit方法调用的......

  protected override void OnPreInit(EventArgs e)
        {
  ...
  ...
  ...
        if ((control != null && control.ClientID ==
                        btnAddControl.ClientID) || createAgain)
        {
        ...
        ...
        ...

            CreateUserControl(controlID);
        }

我的用户控件中的删除按钮的OnClick方法设置为deleteBtn_Click

  protected void deleteBtn_Click(object sender, EventArgs e)
    {
        onDelBtnClk(e);
    }

调用虚拟方法onDelBtnClk

   protected virtual void onDelBtnClk(EventArgs e)
        {
            deleteBtnClk(this, e);
        }

并将此事件和eventargs传递给委托,该委托将用户控件创建和呈现分配给方法后面的方法ucSimpleControl_deleteBtnClk

 void ucSimpleControl_deleteBtnClk(object sender, EventArgs e)
        {
            usercontrols.SimpleControl ucSimpleControl =
                ((usercontrols.SimpleControl)(sender));
            ucSimpleControl.Parent.Controls.Remove(ucSimpleControl);
            Session.Remove((ucSimpleControl.Num).ToString());
            CreateUserControl(controlID);
        }

在这里,我尝试通过获取父控件并使用sender用户控件作为参数调用Controls.Remove方法来删除用户控件。然后,我从Session中删除与用户控件关联的键值对,最后再次调用CreateUserControl以在Session中呈现所有用户控件。但行为很奇怪,只删除了最近创建的用户控件,而不是与单击删除按钮相关联的用户控件,并且在删除一个用户控件后,我无法添加超过当时存在的用户控件数量这页纸。比如,例如,如果页面上有5个用户控件,并且我删除了一个,那么尝试添加更多,我将无法添加超过5,尽管我应该能够添加无限多。这是完整的来源......

DisplayPage.aspx.cs

namespace UserControls4
{
    public partial class DisplayPage : System.Web.UI.Page
    {
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void btnAddControl_Click(object sender, EventArgs e)
    {
        // Create instance of the UserControl SimpleControl
        usercontrols.SimpleControl ucSimpleControl =
          LoadControl("~/usercontrols/SimpleControl.ascx")
          as usercontrols.SimpleControl;

        // Set the Public Properties
        ucSimpleControl.FirstName.Text = "Milind";
        ucSimpleControl.LastName.Text = "Chavan";

        //Create Event Handler for btnPost Click 
        ucSimpleControl.btnPostClk +=
                new usercontrols.btnPost_Click(ucSimpleControl_btnPostClk);
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ucSimpleControl.deleteBtnClk +=
            new usercontrols.deleteBtn_Click(ucSimpleControl_deleteBtnClk);
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////

        //Add the SimpleControl to Placeholder
        Placeholder1.Controls.Add(ucSimpleControl);

        // Add the instance of the SimpleControl to Session Variable
        Session.Add((Session.Count + 1).ToString(), ucSimpleControl);

        // Set createAgain = true
        createAgain = true;
    }

    void ucSimpleControl_btnPostClk(object sender, EventArgs e)
    {
        usercontrols.SimpleControl ucSimpleControl =
                    ((usercontrols.SimpleControl)(sender));
        lblUser.Text = "Welcome " + ucSimpleControl.FirstName.Text +
                       " " + ucSimpleControl.LastName.Text;
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////
    void ucSimpleControl_deleteBtnClk(object sender, EventArgs e)
    {
        usercontrols.SimpleControl ucSimpleControl =
            ((usercontrols.SimpleControl)(sender));
        ucSimpleControl.Parent.Controls.Remove(ucSimpleControl);
        Session.Remove((ucSimpleControl.Num).ToString());
        CreateUserControl(controlID);
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////

    // Declare 2 variable to handle user control after postback
    const string controlID = "MyUserControl";
    static bool createAgain = false;

    protected Control GetPostBackControl(Page page)
    {
        Control control = null;
        try
        {
            string ctrlName = page.Request.Params.Get("__EVENTTARGET");

            if (ctrlName != null && ctrlName != String.Empty)
            {
                control = page.FindControl(ctrlName);
            }
            else
            {
                ContentPlaceHolder cph =
                  (ContentPlaceHolder)page.FindControl("Main");
                for (int i = 0, len = page.Request.Form.Count; i < len; i++)
                {
                    string[] ctl = page.Request.Form.AllKeys[i].Split('$');
                    if (ctl.Length > 3)
                    {
                        control = cph.FindControl(ctl[2])
                                  as System.Web.UI.WebControls.Button;
                    }

                    if (control != null) break;
                }
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
        return control;
    }

    protected override void OnPreInit(EventArgs e)
    {
        base.OnPreInit(e);

        Control control = GetPostBackControl(this.Page);

        // Check if the postback is caused by the button 
        // Titled "Click to Create a Dynamic Control"
        // OR
        // createAgain field is true 
        // which means a call is made to the server while the 
        // user control is active  

        if ((control != null && control.ClientID ==
                        btnAddControl.ClientID) || createAgain)
        {
            //should be set before the CreateUserControl method
            createAgain = true;

            CreateUserControl(controlID);
        }
    }

    protected void CreateUserControl(string controlID)
    {
        // createAgain field is set to true in the OnPreInit method
        // when the 'Create User Control' button is clicked 

        // the createAgain field is used to check if the
        // user control is on the page before the call 
        // if so create the control again and add it to the
        // Control Hierarchy again
        try
        {
            if (createAgain && Placeholder1 != null)
            {
                if (Session.Count > 0)
                {
                    Placeholder1.Controls.Clear();
                    int simpleControlCount = 0;
                    for (int i = 0; i < Session.Count; i++)
                    {
                        switch (Session[i].ToString())
                        {
                            case "ASP.usercontrols_simplecontrol_ascx":
                                {
                                    // Keep count of all SimpleControls
                                    simpleControlCount++;
                                    // Create instance of the UserControl SimpleControl
                                    usercontrols.SimpleControl ucSimpleControl =
                                      LoadControl("~/usercontrols/SimpleControl.ascx")
                                      as usercontrols.SimpleControl;

                                    // Set the Public Properties
                                    ucSimpleControl.FirstName.Text =
                                      ((usercontrols.SimpleControl)(Session[i])).FirstName.Text;
                                    ucSimpleControl.LastName.Text =
                                      ((usercontrols.SimpleControl)(Session[i])).LastName.Text;
                                    ucSimpleControl.Num = simpleControlCount;

                                    //Create Event Handler for btnPost Click 
                                    ucSimpleControl.btnPostClk +=
                                      new usercontrols.btnPost_Click(ucSimpleControl_btnPostClk);

                                    /////////////////////////////////////////////////////////////////////////////////////////////////////////
                                    ucSimpleControl.deleteBtnClk +=
                                         new usercontrols.deleteBtn_Click(ucSimpleControl_deleteBtnClk);
                                    //////////////////////////////////////////////////////////////////////////////////////////////////////////

                                    //Add the SimpleControl to Placeholder
                                    Placeholder1.Controls.Add(ucSimpleControl);
                                    break;
                                }
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

}

}

DisplayPage.aspx

<head id="Head1" runat="server">
    <title>This is example of how to add usercontrol dynamically</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
            <asp:Button ID="btnAddControl" runat="server" 
              Text="Click to add SimpleControl" 
              onclick="btnAddControl_Click" />
            <br />
            <asp:PlaceHolder runat="server" 
           ID="Placeholder1" ></asp:PlaceHolder>
            <br />
            <asp:Label ID="lblUser" 
              runat="server"></asp:Label>
    </div>
    </form>
</body>
</html>

SimpleControl.ascx.cs

namespace UserControls4.usercontrols
{
    public delegate void btnPost_Click(object sender, System.EventArgs e);
    public delegate void deleteBtn_Click(object sendre, System.EventArgs e);

    public partial class SimpleControl : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        private int num;

        #region Public Event

        public event btnPost_Click btnPostClk;
        public event deleteBtn_Click deleteBtnClk;

        #endregion

        #region Public Properties

        public TextBox FirstName
        {
            get
            {
                return txtFirstName;
            }
            set
            {
                txtFirstName = value;
            }
        }

        public TextBox LastName
        {
            get
            {
                return txtLastName;
            }
            set
            {
                txtLastName = value;
            }
        }

        public int Num
        {
            get { return this.num; }
            set { this.num = value; }
        }
        #endregion

        #region Vitual Methods

        protected virtual void OnbtnDelQtnMrClk(EventArgs e)
        {
            // Call btnPost_Click event delegate instance
            btnPostClk(this, e);
        }

        /// ///////////////////////////////////////////////////////////////////////////////////////
        protected virtual void onDelBtnClk(EventArgs e)
        {
            deleteBtnClk(this, e);
        }

        /// /////////////////////////////////////////////////////////////////////////////////////////

        #endregion

        protected void btnPost_Click(object sender, EventArgs e)
        {
            //Call Virtual Method
            OnbtnDelQtnMrClk(e);
        }

        ///////////////////////////////////////////////////////////////////////////////////////////
        protected void deleteBtn_Click(object sender, EventArgs e)
        {
            onDelBtnClk(e);
        }

    }
}

SimpleControl.ascx

<table>
    <tr>
        <td><asp:Label ID="label1" runat="server" 
            Text="First Name" ></asp:Label></td>
        <td> <asp:TextBox ID="txtFirstName" 
            runat="server"></asp:TextBox></td>
    </tr>
     <tr>
        <td><asp:Label ID="label2" runat="server" 
           Text="Last Name" ></asp:Label></td>
        <td> <asp:TextBox ID="txtLastName" 
           runat="server"></asp:TextBox></td>
    </tr>
    <tr>
        <td><asp:Button ID="btnPost"  runat="server" 
            Text="Send Info" OnClick="btnPost_Click" />
        </td>
    </tr>
</table>
<obout:SuperForm ID="UserControlSuperForm" 
    Width="630" Title="SuperForm"
    AutoGenerateRows="false"
    RunAt="server"
    DefaultMode="Insert"
    FolderStyle="styles/black_glass">
    <Fields>
        <obout:TemplateField HeaderText="SuperForm">
            <EditItemTemplate>
                <asp:TextBox ID="superFormTxt" runat="server"></asp:TextBox>
            </EditItemTemplate>
        </obout:TemplateField>
    </Fields>
</obout:SuperForm>
<asp:Button ID="removeBtn" runat="server" Text="Remove" OnClick="deleteBtn_Click"/>

1 个答案:

答案 0 :(得分:1)

除了El Ronnoco的评论之外,动态添加和删除控件要求在回发期间添加每个控件,但更重要的是,每个控件都有唯一的ID。 ASP.NET运行时按ID挂接事件,因此如果要添加的每个控件都没有唯一的ID,则不会触发事件。