0

几周前,我创建了一个模板化用户控件,大部分基于此处的示例: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,也是第一次尝试动态填充/加载它,所以我确信我缺少完成此操作所需的一些东西。任何帮助是极大的赞赏。

- 安德鲁

4

2 回答 2

1

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

不正确:

xpcRegion = new ExpandCollapseRegion();

正确的:

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

做出这个简单的改变就解决了这个问题。另外,发现我可以ITemplate通过使用该CompiledTemplateBuilder()方法放弃对自定义类的需求。真正简化了代码。

- 安德鲁

于 2011-08-16T15:44:44.260 回答
0

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

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

于 2011-08-16T01:36:08.950 回答