Click here to Skip to main content
15,885,767 members
Please Sign up or sign in to vote.
2.33/5 (3 votes)
A few weeks back I created a Templated User Control, for the most part based on the example here:
http://msdn.microsoft.com/en-us/library/36574bf6(v=VS.90).aspx

The difference is that I did not implement the "MessageContainer" class as I wanted just an empty template that I could add whatever controls I wanted to at design time.

This TUC has been working great, but I ran into a scenario I hadn't anticipated when I created the thing. The need to dynamically add this TUC to a page, which means that I would need to dynamically add the controls within the template of the TUC as well.

I found another example here on how to dynamically create a Template and add it to the Templated Control:
http://msdn.microsoft.com/en-us/library/y0h809ak(v=vs.71).aspx

This second example article discusses only the "DataList, Repeater, and DataGrid controls" but I figure since I am using the ITemplate interface here, it should be the same thing.

However, I am unable to get this to work, I keep getting an "Object reference not set to an instance of an object." error when I attempt to populate the TUC.

Here's what I am doing....

Like the example above I created an ITemplate class:

C#
public class XPCTemplate : ITemplate
{
    private readonly Control _control;
    public XPCTemplate(Control control)
    {
        _control = control;
    }

    public void InstantiateIn(Control container)
    {
        container.Controls.Add(_control);
    }
}


Then, in the test page code-behind I attempt to load up and display the TUC dynamically:

C#
ExpandCollapseRegion xpcRegion;  // The Templated User Control

protected void Page_Load(object sender, EventArgs e)
{
    PlaceHolder ph;
    // ...dynamically create some labels, textboxes, etc...;

    // Create an instance of the TUC
    xpcRegion = new ExpandCollapseRegion();

    // Pass into the TUC's template the controls dynamically created above
    xpcRegion.LayoutTemplate = new XPCTemplate(ph);

    // add the dynamic TUC to the page
    phDynamicUC.Controls.Add(xpcRegion);

    phDynamicUC.Controls.Add(new LiteralControl("<br />"));
}


Test page HTML Source:

ASP.NET
<body>
    <form id="form1"  runat="server">
    <div>
    
    Dynamically Loading User Control
    <br />
    <asp:PlaceHolder ID="phDynamicUC" runat="server" />
    
    </div>
    </form>
</body>



When I run the page, I get the "Object reference not set to an instance of an object" error on the "container.Controls.Add(_control);" line of the XPCTemplate class. When I debug the test page and TUC control, the code of the TUC receives the XPCTemplate into its LayoutTemplate during the TUC's Page_Init() method, but when the InstantiateIn() event back in the XPCTemplate fires immediately afterwards, the "container" argument is NULL.

I'm not sure why this is happening, it's like the InstantiateIn() method of the XPCTemplate class is trying to actually set the PlaceHolder control within the TUC rather than just passing the contents. Maybe this is supposed to be the way and I am missing something on the TUC side to allow this behavior?

This is the first TUC I have created and likewise the first time trying to dynamically fill/load it, so I am sure I am missing something needed to accomplish this. Any help is greatly appreciated.

-- Andrew
Posted
Updated 15-Aug-11 10:13am
v2
Comments
Wonde Tadesse 15-Aug-11 19:44pm    
What is ExpandCollapseRegion class ?

1 solution

Found the solution to the problem, which was how I was loading the TUC.

Incorrect:
C#
xpcRegion = new ExpandCollapseRegion();



Correct:
C#
xpcRegion = (ExpandCollapseRegion)LoadControl("ExpandCollapseRegion.ascx");


Making this simple change took care of the problem. Also, found that I could forego the need for a custom ITemplate class by using the CompiledTemplateBuilder() method. Really simplifies the code.

-- Andrew
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900