Dynamically add a user control to a repeater

I have a class (MyClass), which is a nested hierarchy, so the class has a property that is a collection of MyClass. MyClass also has a title property

To show it on a web page, I was hoping to create a custom repeater control. In the element template, I will have a literal display of the title property, and in the ItemCreated event of the relay I will create a new instance of usercontrol and add it to the current element in the relay.

My problem is that when the Page_Load event is fired in usercontrol, if the control was dynamically added, the repoperler repetery repeter is null, even if I call EnsureChildControls. Am I missing something? If I create a repeater and drop my userctonrol in the element template, it works fine. Can I get this to work dynamically?

User control:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MyControl.ascx.cs" Inherits="MyControl" %>
Items:<br/>
<asp:Repeater ID="repMyClass" runat="server" EnableViewState="false" 
    OnItemCreated="repMenuItems_ItemCreated">
    <HeaderTemplate><ul><HeaderTemplate>
    <ItemTemplate>
        <li><%# Eval("Title") %>
            <div><asp:PlaceHolder ID="SubItemPlaceholder" runat="server" /></div>
        </li></ItemTemplate>
    <FooterTemplate></ul></FooterTemplate>
</asp:Repeater>

User Management Code:

public partial class MyControl: System.Web.UI.UserControl
{
    public IEnumerable<MyClass> ChildItems { get; set; }
    protected void Page_Load(object sender, EventArgs e)
    {
        this.repMyClass.DataSource = ChildItems;
        this.repMyClass.DataBind();
    }

    protected void repMenuItems_ItemCreated(object Sender, RepeaterItemEventArgs  e)
    {
        if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
        {
            //Get the MyClass instance for this repeater item
            MyClass mcCurrent = (MyClass)e.Item.DataItem;

            //If the MyClass instance has child instances
            if (mcCurrent.Children != null && mcCurrent.Children.Length > 0)
            {
                //Add a new user control and set it property so it can bind
                PlaceHolder ph = (PlaceHolder)e.Item.FindControl("SubItemPlaceholder");

                MyControl ctl = (MyControl)Page.LoadControl(typeof(MyControl),new object[] {});

                ctl.ChildItems = mcCurrent.Children;
                ph.Controls.Add(ctl);
            }
        }
    }
}
+5
source share
2 answers

I have done this for a long time to create nested reports using Accordions.

In the index, when you want to dynamically add instances of User Control:

// Declare Placeholder    
PlaceHolder ph = (PlaceHolder)e.Item.FindControl("SubItemPlaceholder")

// Adding some literal controls to header
ph.Controls.Add(new LiteralControl("This is the accordion header!!"));

// Declare new control variable
crt = new Control();

// Load up your User Control
crt = LoadControl("~/MyControl.ascx");

// Check if it has loaded properly
if (crt != null)
{
    // GET / SET any custom properties of the User Control
    ((myClass)crt).title = "Welcome";

    // Add the new User Control to the placeholder controls collection
    ph.Controls.Add(crt);
}

: User Control "ClassName"

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyControl.ascx.cs" Inherits="myTest" ClassName="myClass" %>

, , , :

public string title { get; set; }

, "repMyClass", , .

+3

, , , , LoadControl().

, , Load , , .

- , .

- :

<uc:MyControl runat="server 
    ChildItems='<%# ((MyClass) Container.DataItem).Children %>'
    Visible='<%# ((MyClass) Container.DataItem).Children.Length > 0 %>'
    />

, , Bound Data Data Bound Item Created.

, , , e.Item.DataItem hasn; t .

ItemDataBound , .

.

( ItemDataBound). - e.Item.FindControl("ControlId") as MyControl ( null, ).

, , ...

0

All Articles