几周前,我创建了一个模板化用户控件,大部分基于此处的示例: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() 事件随后立即触发时,“容器”参数是无效的。
我不确定为什么会发生这种情况,就像 XPCTemplate 类的 InstantiateIn() 方法试图在 TUC 中实际设置 PlaceHolder 控件,而不仅仅是传递内容。也许这应该是这种方式,而我在 TUC 方面遗漏了一些东西来允许这种行为?
这是我创建的第一个 TUC,也是第一次尝试动态填充/加载它,所以我确信我缺少完成此操作所需的一些东西。任何帮助是极大的赞赏。
- 安德鲁