C# – Issue with dynamically loading a user control on button click

asp.netcuser-controls

I have a page in which I am loading a user control dynamically as follows:

Default.aspx:

    <cc1:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
    </cc1:ToolkitScriptManager>

    <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>

Default.aspx.cs:

    protected void Page_Load(object sender, EventArgs e)
    {
        var ctrl = LoadControl("~/UserCtrl1.ascx");
        ctrl.ID = "ucUserCtrl1";
        PlaceHolder1.Controls.Add(ctrl);
    }

Below is the code for UserCtrl1.ascx

<asp:Label ID="Label1" runat="server"></asp:Label>
<asp:Button ID="Button1" runat="server" Text="Button1" OnClick="Button1_Click" />
<br />
<asp:PlaceHolder ID="PlaceHolder2" runat="server"></asp:PlaceHolder>

I am dynamically loading another user control when the Button1 is clicked

UserCtrl1.ascx.cs

    protected void Button1_Click(object sender, EventArgs e)
    {
        Label1.Text = "UserControl - 1 button clicked!";

        var ctrl = LoadControl("~/UserCtrl2.ascx");
        ctrl.ID = "ucUserCtrl2";
        PlaceHolder2.Controls.Add(ctrl);
    }

Below is the markup for UserCtrl2.ascx

<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <asp:Label ID="Label2" runat="server"></asp:Label>
        <asp:Button ID="Button2" runat="server" Text="Button2" OnClick="Button2_Click" />
    </ContentTemplate>
</asp:UpdatePanel>

UserCtrl2.ascx.cs

    protected void Button2_Click(object sender, EventArgs e)
    {
        Label2.Text = "UserControl - 2 button clicked!";
    }

After the page loads when I click the Button1 in UserCtrl1 the click event fires and I am able to see the Label1 text. It also properly loads the UserCtrl2, but when I click the Button2 in UserCtrl2 the click event dosent fire and even worse when I click the Button2 twice the UserCtrl2 control dissappears from the page. How can I fix this?

Best Answer

The problem with the second control is that you are loding it only after the click of button 1. But when some other (not button 1 click) postback happens your second control is not loaded.

One of possible fixes is saving some flag (e.g. in ViewState) that will help you to determine if your second control should be loaded (and load in on page load).

protected void Button1_Click(object sender, EventArgs e)
{
    Label1.Text = "UserControl - 1 button clicked!";

    var ctrl = LoadControl("~/UserCtrl2.ascx");
    ctrl.ID = "ucUserCtrl2";
    PlaceHolder2.Controls.Add(ctrl);

    this.SecondControlLoaded = true; // This flag saves to ViewState that your control was loaded.
}

protected void Page_Load(object sender, EventArgs e)
{
    var ctrl = LoadControl("~/UserCtrl1.ascx");
    ctrl.ID = "ucUserCtrl1";
    PlaceHolder1.Controls.Add(ctrl);

    if (this.SecondControlLoaded)
    {
        var ctrl = LoadControl("~/UserCtrl2.ascx");
        ctrl.ID = "ucUserCtrl2";
        PlaceHolder2.Controls.Add(ctrl);
    }
}
Related Topic