ASP.NET:如何销毁动态添加的用户控件

ASP.NET:如何销毁动态添加的用户控件,asp.net,user-controls,Asp.net,User Controls,我将用户控件添加到ID为phCustomFields的占位符中。当我想删除phCustomFields中的用户控件时,我调用phCustomFields.Controls.Clear()。但是,在执行此操作之后,我的usercontrol的Page_Load方法仍然会被命中(我通过在用户控件中放置断点来验证这一点)。为什么我的用户控件的Page_Load方法仍然被调用?我认为调用Clear()方法后,我的用户控件的实例就被删除并销毁了 更新 下面是一些示例代码,演示了我的问题。通过在HelloW

我将用户控件添加到ID为phCustomFields的占位符中。当我想删除phCustomFields中的用户控件时,我调用phCustomFields.Controls.Clear()。但是,在执行此操作之后,我的usercontrol的Page_Load方法仍然会被命中(我通过在用户控件中放置断点来验证这一点)。为什么我的用户控件的Page_Load方法仍然被调用?我认为调用Clear()方法后,我的用户控件的实例就被删除并销毁了

更新

下面是一些示例代码,演示了我的问题。通过在HelloWorld.ascx的Page_Load方法和debuging Page.aspx处设置断点,调试过程将在HelloWorld.ascx中的Page_Load方法处停止,这是我所期望的,并且没有问题。但是,当我单击“Remove HelloWorld.ascx”按钮删除用户控件,然后单击“Do Nothing”按钮导致回发时,调试过程仍然会在HelloWorld.ascx的Page_Load方法处停止。但是,这不应该发生,因为调用了phTest中的Clear()方法

Page.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Page.aspx.cs" Inherits="WebApplication1.Page" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        Control C = LoadControl("HelloWorld.ascx");
        phTest.Controls.Add(C);
    }

    protected void Remove_OnClick(object sender, EventArgs e)
    {
        phTest.Controls.Clear();
    }

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

        <asp:Button  Text="Does nothing" runat="server" />
        <asp:Button Text="Remove HelloWorld.ascx" OnClick="Remove_OnClick" runat="server" />
        <asp:PlaceHolder ID="phTest" Visible="false" runat="server">
        </asp:PlaceHolder>
    </div>
    </form>
</body>
</html>
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="HelloWorld.ascx.cs" Inherits="WebApplication1.HelloWorld" %>
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        int i = 0;
    }
</script>

<b>Hello World</b>

受保护的无效页面加载(对象发送方、事件参数e)
{
控件C=加载控件(“HelloWorld.ascx”);
phTest.Controls.Add(C);
}
受保护的void Remove\u OnClick(对象发送方,事件参数e)
{
phTest.Controls.Clear();
}
HelloWorld.ascx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Page.aspx.cs" Inherits="WebApplication1.Page" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        Control C = LoadControl("HelloWorld.ascx");
        phTest.Controls.Add(C);
    }

    protected void Remove_OnClick(object sender, EventArgs e)
    {
        phTest.Controls.Clear();
    }

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

        <asp:Button  Text="Does nothing" runat="server" />
        <asp:Button Text="Remove HelloWorld.ascx" OnClick="Remove_OnClick" runat="server" />
        <asp:PlaceHolder ID="phTest" Visible="false" runat="server">
        </asp:PlaceHolder>
    </div>
    </form>
</body>
</html>
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="HelloWorld.ascx.cs" Inherits="WebApplication1.HelloWorld" %>
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        int i = 0;
    }
</script>

<b>Hello World</b>

受保护的无效页面加载(对象发送方、事件参数e)
{
int i=0;
}
你好,世界
Clear()
肯定会从控件树中删除控件,从而删除页面生命周期。在内部,它将对控件的引用设置为null

如果该控件的另一个实例位于控件树中的其他位置,或者您没有按照自己的想法尽早调用
Clear
,或者没有在正确的集合中调用它,则仍然可能发生这种情况。在页面生命周期的什么时候调用Clear()


Edit:您正在调用
Remove\u OnClick
evnet处理程序中的
Clear
,该处理程序在为所有控件触发页面加载后很久才调用。在页面移动到下一个事件之前,将为页面和所有控件触发OnLoad。

OnClick事件发生在页面生命周期中的页面加载事件之后。在回发时,仍将调用用户控件页面加载事件。如果稍后在父页面生命周期中使用Clear()命令,应该会有所帮助

根据您的更新进行编辑。用户控件的页面加载每次都发生的原因是,在.aspx页面的页面加载事件中,您拥有将该控件添加到页面的代码。基本上,每次请求页面时,都会将该用户控件添加到页面中(并点击用户控件页面加载事件)


如果希望某个操作在回发时发生/不发生,请使用页面的IsPostBack属性。不确定您想对页面做什么,但希望这能有所帮助。

以下是webforms页面生命周期中的一些相关亮点:

  • 已处理页面加载事件
  • 回发事件,包括已处理的单击事件
  • 已处理页面预呈现事件

  • 因此,您可以选择在Page_PreRender事件处理程序中的控件中执行需要执行的任何处理,而不是Page_Load。由于这是在处理回发事件之后发生的,因此,如果控件已被删除,则不会发生这种情况。

    能否向我们展示一些代码?我已更新了我的问题以回答您的问题。我在呼叫第页的Clear()。哦,我真傻。我创建了一个如此愚蠢的示例,忘记在添加用户控件的代码周围添加if(!IsPostback)条件