动态添加控件到模板化用户控件?

时间:2011-08-15 20:04:43

标签: c# asp.net user-controls dynamic itemplate

几个星期前,我创建了一个模板化用户控件,大部分基于此处的示例: http://msdn.microsoft.com/en-us/library/36574bf6(v=VS.90).aspx

不同之处在于我没有实现“MessageContainer”类,因为我只想要一个空模板,我可以在设计时添加我想要的任何控件。

这个TUC一直很好用,但是当我创建这个东西时,我遇到了一个我没预料到的场景。需要动态地将此TUC添加到页面,这意味着我还需要在TUC的模板中动态添加控件。

我在这里找到了另一个关于如何动态创建模板并将其添加到模板化控件的示例: http://msdn.microsoft.com/en-us/library/y0h809ak(v=vs.71).aspx

这个第二篇文章只讨论了“DataList,Repeater和DataGrid控件”,但我想,因为我在这里使用的是ITemplate接口,所以它应该是一样的。

但是,我无法让它工作,我不断得到一个“对象引用未设置为对象的实例”。我尝试填充TUC时出错。

这就是我正在做的事情......

与上面的例子一样,我创建了一个ITemplate类:

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

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

然后,在测试页面代码隐藏中,我尝试动态加载并显示TUC:

ExpandCollapseRegion xpcRegion;  // The Templated User Control

protected void Page_Load(object sender, EventArgs e)
{
    PlaceHolder ph;
    // ....  code here to 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 />"));
}

测试页面HTML来源:

<body>
    <form id="form1" runat="server">
    <div>

    Dynamically Loading User Control
    <br />
    <asp:PlaceHolder ID="phDynamicUC" runat="server" />

    </div>
    </form>
</body>

当我运行页面时,我在“container.Controls.Add(_control);”上得到“对象引用未设置为对象的实例”错误XPCTemplate类的行。当我调试测试页面和TUC控件时,TUC的代码在TUC的Page_Init()方法中将XPCTemplate接收到其LayoutTemplate中,但是当XPCTemplate中的InstantiateIn()事件在之后立即触发时,“container”参数为NULL。

我不确定为什么会发生这种情况,就像XPCTemplate类的InstantiateIn()方法试图在TUC中实际设置PlaceHolder控件而不是仅传递内容。也许这应该是方式而我在TUC方面遗漏了一些允许这种行为的东西?

这是我创建的第一个TUC,同样是第一次尝试动态填充/加载它,所以我确信我缺少完成此任务所需的东西。非常感谢任何帮助。

- 安德鲁

2 个答案:

答案 0 :(得分:1)

找到问题的解决方案,这就是我加载TUC的方式。

不正确:

xpcRegion = new ExpandCollapseRegion();

正确:

xpcRegion = (ExpandCollapseRegion)LoadControl("ExpandCollapseRegion.ascx");

进行这种简单的改变可以解决问题。另外,发现我可以使用ITemplate方法放弃对自定义CompiledTemplateBuilder()类的需求。真的简化了代码。

- 安德鲁

答案 1 :(得分:0)

我认为问题在于您没有实例化您传入模板的PlaceHolder ph。因此,它抱怨的行是因为它无法将控件添加到PlaceHolder,因为它是null / nothing。

另外,我相信你需要把你的占位符放在某个地方。否则,您要将项目添加到从未添加到页面的容器中。