【问题标题】:ASP.NET: How to destroy dynamically added User ControlASP.NET:如何销毁动态添加的用户控件
【发布时间】:2009-11-03 21:08:49
【问题描述】:

我将用户控件添加到 ID 为 phCustomFields 的 PlaceHolder。当我想删除 phCustomFields 中的用户控件时,我调用 phCustomFields.Controls.Clear()。然而,在这样做之后,我的用户控件的 Page_Load 方法仍然被命中(我通过在用户控件中放置一个断点来验证这一点。)为什么我的用户控件的 page_load 方法仍然被调用?我认为一旦我调用 Clear() 方法,我的用户控件的实例就被删除并销毁了。

更新

这是一些演示我的问题的示例代码。通过在 HelloWorld.ascx 的 Page_Load 方法处设置断点并调试 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>

HelloWorld.ascx

<%@ 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>

【问题讨论】:

  • 你能给我们看一点代码吗?

标签: asp.net user-controls


【解决方案1】:

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

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

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

【讨论】:

  • 哦,我真傻。我创建了一个如此愚蠢的示例,我忘记在添加用户控件的代码周围添加 if (!IsPostback) 条件
【解决方案2】:

Clear() 肯定会从控件树中删除控件,从而删除页面生命周期。在内部,它将对控件的引用设置为 null。

这种情况仍然会发生的唯一方法是,如果该控件的另一个实例存在于控件树的其他位置,或者您没有像您想的那样早调用Clear,或者没有在正确的集合上调用它。您在页面生命周期的哪个时间点调用 Clear()?

编辑:您在Remove_OnClick evnet 处理程序中调用Clear,这是在Page_Load 为所有控件触发之后很久。 OnLoad 将在页面和所有控件移动到下一个事件之前触发。

【讨论】:

  • 我已更新我的问题以回答您的问题。我在 Page_Load 上调用 Clear()。
【解决方案3】:

以下是网络表单页面生命周期中的一些相关亮点:

  1. 已处理页面加载事件
  2. 回发事件,包括处理的点击事件
  3. 页面预渲染事件已处理

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 2012-02-11
    • 2017-01-10
    • 2021-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多