views:

405

answers:

3

I added user control to a PlaceHolder with an ID phCustomFields. When I want to remove the user control in phCustomFields, i call phCustomFields.Controls.Clear(). However, after doing this, my usercontrol's Page_Load method still gets hit (i verified this by putting a breakpoint in the user control.) Why is my user control's page_load method still being called? i thought the instance of my user control was removed and destroyed once i called the Clear() method.

Update

Here is some sample code that demonstrates my problem. By setting the breakpoint at the Page_Load method of HelloWorld.ascx and debugging Page.aspx, the debug process would stop at the Page_Load method in HelloWorld.ascx which is expected and fine by me. But when I click on "Remove HelloWorld.ascx" button to remove the user control and then click on "Do Nothing" button to cause a postback, the debug process STILL stops at HelloWorld.ascx's Page_Load method. However, this shouldn't happen because the Clear() method in phTest was called.

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"&gt;
<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>
A: 

Clear() definitely removes the controls from the control tree and hence the page lifecycle. Internally it sets the reference to the control to null.

The only way this could still be happening is if another instance of that control lives somewhere else in the control tree, or you're not calling Clear as early as you think, or not calling it on the right collection. At what point in the page lifecycle are you calling Clear()?

Edit: you are calling Clear in the Remove_OnClick evnet handler, which is long after Page_Load has fired for all controls. OnLoad will fire for the page and for all controls before it moves on to the next event.

Rex M
I've updated my question answering your question. I'm calling Clear() on Page_Load.
burnt1ce
@burnt1ce see my update.
Rex M
OOPPSSSIEsThanks
burnt1ce
+1  A: 

The OnClick event happens after the Page_Load event in the Page Life Cycle. On a postback the user controls Page_Load event will still be called. If you put the Clear() command later in the parent page life cycle, that should help.

EDIT As per your update. The reason that the Page_Load of the user control is happening every time is because you have the code to add that control to the page in the Page_Load event of your .aspx page. Basically, every time the page is requested, that user control is going to be added to the page(and hit the user control Page_Load event).

If you want a certain action to happen/not happen on a postback use the IsPostBack property of the page. Not sure exactly what you want to do with the page, but hopefully that helps a little bit.

jaywon
OH silly me. I created such a silly example i forgot to add a if (!IsPostback) condition around the code that adds the user control
burnt1ce
A: 

Here's a few relevant highlights from the webforms page life cycle:

  1. Page load event handled
  2. Postback events, including click events handled
  3. Page pre-render event handled

So you have the option of performing whatever processing you need to do in the control in the Page_PreRender event handler instead of Page_Load. As this occurs after the postback events are handled, it will not happen if the control has been removed.

Nick Higgs