Independent
Independent

Reputation: 2987

Events are not working if UserControl.ascx are loaded through LoadControl(ctr)

I find this as a funny little problem. I think the reason lies behind the life-cycle of page-object/events-generation, but the question is how I come around the problem?

In Default.aspx there exist some funny controls but also a
<asp:PlaceHolder runat="server" id="phUserContent"></asp:PlaceHolder>

This placeholder is empty until runtime. Code behind are, in some circumstances, loading UserControls into it. Like this
Control ctr = LoadControl("~/UserControl/Note.ascx"); phUserContent.Controls.Add(ctr);

This Note.ascx contains some interesting controls and finally a LinkButton that fires an event. The LinkButton-code are very easy and gramatically correct,
<asp:LinkButton runat="server" ID="lbUpdate" OnClick="lbUpdate_Click" Text="Update"></asp:LinkButton>

In the Code behind for the ascx I have the code for the event,

protected void lbUpdate_Click(object sender, EventArgs e)
{ ... }

As I wroted, the postback occurs, the page are regenerated as I would suspect - but without the lbUpdate_Click event to be executed. A break-point is of course tried.

I'm looking for two possible scenarios. One is that I missed something really easy (you know, like wroted in wrong code behind file) or that I missed an important part of the Page Generation Cycle.

I'm mostly into the second, like this (i just think here..)
1. Page (ascx) got it's changes 2. Submit was clicked 3. Ascx was re-generated 4. Events was cleared but was exist and doesnt cast error. 5. After reload, initial content was reloaded

The effect would be that the compiler can't see the breakpoint and the values was never saved due to a "execution of an empty event". But this is just a amateours guess, please advice me.

[UPDATE AS PER ANSWER] This is how I was solved it, based on the acepted answer below.

List<Control> ctr;
public User()
{
    ctr = new List<Control>();
}
protected void Page_PreInit(object sender, EventArgs e)
{
    ctr.Add(LoadControl("~/UserControl/Note.ascx"));
}

protected void Page_Load(object sender, EventArgs e)
{
    ctr.ForEach(d => phUserContent.Controls.Add(d));
}

Shortly..
1. The class got a list of Controls
2. In Page_PreInit (before creation) add UC (u can have X of them here)
3. In Page_Load (where all ctr are created) add each UC to the PH.

Which also make the events in the UC also working, no magic and no dumb complications :-)

Upvotes: 0

Views: 1960

Answers (1)

womp
womp

Reputation: 116977

It's a lifecycle issue.

Remember, every page request creates a new Page object, and new instances of all the controls on it. If you are dynamically creating a control, then it has to be done in the exact same manner on every postback. If you want the new control to fire an event, then it has to have the same id as the old one, and have the event hooked up to it before control events are processed in the lifecycle.

If you're creating the control dynamically at a point in the page lifecycle that occurs after ViewState is handled, then you'll have to manage your own state as well. In other words, if you're not dynamically creating the control during the PreInit phase, then you'll have to manually deal with restoring state.

Upvotes: 2

Related Questions