1

I need to add a UserControl dynamicaaly to a Panel on a page. The UserControl has a Repeater with the ID of ARepeater. I load and add the UC on Page_Init. I examine the value of ARepeater in Init, Load, and PreRender events of UC but ARepeater is always null.

protected Page_Init(object sender, EventArgs e)
{
  var list = (NameList)Page.LoadControl(typeof(NameList), new object[1] { (int)Type });
  Panel1.Controls.Add(list);
}

The NameList.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="NameList.ascx.cs" Inherits="MyCompant.Controls.BannersList" %>
   <asp:Repeater ID="ARepeater" runat="server">
      <ItemTemplate>
      </ItemTemplate>
    </asp:Repeater>

What I am doing wrong?

2 Answers2

1

First of all, you do not need to be in Page_Init to work with dynamic controls. Page_Load is just fine. But in order to fill the Repeater you can create a property in the UserControl

public partial class WebUserControl1 : System.Web.UI.UserControl
{
    public Repeater _ARepeater
    {
        get
        {
            return ARepeater;
        }
        set
        {
            ARepeater = value;
        }
    }


    protected void Page_Load(object sender, EventArgs e)
    {
    }

Then you can access it from the page using the UserControl.

protected void Page_Load(object sender, EventArgs e)
{
    var list = (WebUserControl1)LoadControl("~/WebUserControl1.ascx");
    list.ID = "MyUserControl";
    Panel1.Controls.Add(list);

    list._ARepeater.DataSource = source;
    list._ARepeater.DataBind();
}

Or use FindControl

var _ARepeater = (Repeater)Panel1.FindControl("MyUserControl").FindControl("ARepeater");
_ARepeater.DataSource = dt;
_ARepeater.DataBind();
VDWWD
  • 35,079
  • 22
  • 62
  • 79
0

You probably won't like this answer, but the overload for Page.LoadControl that allows for specifying the control's type and adding constructor arguments doesn't bind the ascx to the code-behind, and all associated child-controls will end up being null.

In the past, I've worked around this by adding another method for setting dependencies after constructing the user control, but it's not an ideal solution.

That said you aren't doing anything wrong. Binding will work properly if you use Page.LoadControl("~/path/to/mycontrol.ascx"), but you won't have constructor injection.

I believe the issue lies with the fact that the backing class doesn't actually have a relationship with the front-end page, except through the page directive that specifies it as the code-behind class. Nothing stops multiple different front-ends using the same class as it's code-behind, so loading by Type makes it either very difficult or outright impossible to determine what the correct ascx to bind would be.

Jonathon Chase
  • 9,396
  • 21
  • 39