asp.net复合自定义控件上的奇怪行为 - 任何人都有答案?

时间:2011-10-19 17:46:42

标签: asp.net controls composite

情景

我现在正在开发一个大型网络表格的内部网站,我们正在尝试用通用的,数据库驱动的表单引擎替换500多个表单,这将动态添加各种​​字段和验证并连接任何下拉绑定等等。到目前为止,非常好。

我们如何做到这一点相当容易;我们有一个在页面初始化期间调用的例程,它获取适当的字段定义和相关的验证器(客户端和自定义),并基本上将每个依次添加到占位符。

作为职权范围的一部分,我们需要为“平台”之类的东西创建一些复合控件,这些控件具有一些特定的服务器端功能,我们无法真正做到通用,但是它们在各处都使用。

计划是简单地扩展当前设计,以便在需要时将这些复合控件的实例添加到占位符中。

但是,这些控件在Load和PreRender上执行某些操作,这是我们遇到问题的地方。

问题

回想一下,我们在Init中做了所有这些事情?好吧,我们需要构建诸如动态服务器端自定义验证器之类的东西(我们在数据库中保存它们的方法名称,并且在实例化相关控件之后基本上使用反射连接)。

我们能够以这种方式添加复合控件的实例,并且一切都很好。然而,当控件的Load或PreRender事件被触发时,我们发现了一个奇怪的事情(这就是我需要你聪明的人来帮助我的地方)。

基本上,当我想访问此复合控件上的任何子控件时,我得到一个NullReferenceException。这些是简单的事情,比如我要隐藏的图像(在.ascx上是声明的而不是动态的)和下拉列表(我想从数据库中填充一些值)。奇怪的是,即使我将这个代码移到PreRender,这些控件似乎也没有被实例化,即使它们应该被声明它们是声明的,并且我们处于PreRender阶段。

这是一个典型的片段(道歉,由于客户端限制而在VB.NET 2.0中 - 这就是它的原因; - ):

Me.EnsureChildControls()
IsRequiredFieldIndicator.Visible=IsRequired
If Not IsPostBack Then
    LoadDropDownListFromBLL()
End

当我们尝试对任何实际的子控件执行某些操作时会发生异常,例如IsRequiredFieldIndicator控件(这是一个图像)。换句话说,它不在那里。奇怪的是,当我们检查发生了什么时,ChildControlsCreated属性已设置为true,但Controls集合的内容未显示任何内容(空)。

我在这里缺少一些基本的东西吗?如果我们以声明的方式将复合控件放在页面上,那么复合控件在所有方面都能很好地工作,所以我很想说问题可能与页面生命周期中关于动态添加的复合控件的一些鲜为人知的特性有关。

哦,在有人建议之前,我确保复合控件实现了INamingContainer接口但无济于事。

有没有人遇到过这样的事情,如果有的话,你是怎么解决这个问题的?

非常感谢,

约翰

1 个答案:

答案 0 :(得分:0)

好的,我明白了。它很简单(不是总是吗?)。基本上,答案在于,您根本无法动态创建用户控件的新实例并期望它“正常工作”。你需要使用LoadControl()(当然,我知道,但嘿,完全错过了......)。否则,只需使用new()然后插入值来实例化控件就会错过将.ascx声明性控件“折叠”到实际控件设置中的关键步骤......如果这有意义的话。通过使用new(),一切似乎都有效,但当然控制已经错过了这个重要的步骤,这就是回来咬我的东西..... d'oh!