好的,显而易见的答案是,因为复合控件的流程要求在某个时间点创建我的子控件。我遇到了一个问题,我认为其他人一定也遇到过。
我的控件是一个复合“容器/集合”控件。它将被提供一个对象,并基于该对象数据创建许多子控件。所以我的控件将呈现一个标题(总是)和 x 数,比如 TextBox 控件(基于它所提供的对象)。
我显然在 CreateChildControls() 中创建了我的标题,但我也无法在那里创建我的 TextBoxes,因为我不知道对象(作为 TextBoxes 的基础)是否已经被输入?我想过公开一个属性/方法来设置/提供对象,但我不确定它什么时候会被调用。
那我该怎么办?我的意思是我不可能在 CreateChildControls() 中创建文本框,或者我可以吗?我的意思是 - 什么时候调用 CreateChildControls() - 我知道我可以调用 EnsureChildControls() (我已经在一个属性中设置了标题的 innerText - 因为我需要在设置它的 innerText 之前创建标题)。
这个怎么样
var c = new MyContainerControl();
c.Header = "fun";
c.TextBoxObject = myTextBoxes;
如果我将文本框的构建放在 CreateChildControls() 中,那将引发错误(或充其量不会创建任何文本框)。
将 Header 存储在成员变量中会不会更明智,因此不必在设置 Header 内部文本的公开方法/属性中调用 EnsureChildControls()。我只是不太喜欢这种方法,因为它会通过添加额外的逻辑来临时存储并且稍后必须弄清楚何时设置它(可能在 PreRender 中)会使事情复杂化。
另外我想我可以制作某种数据绑定控件,确保在调用 .DataBind() 时数据存在。我真的不喜欢这个,因为上次我研究了创建数据绑定控件,它变得非常复杂。
这真的应该是一个容易解决的任务 - 我知道我在某处遗漏了一些东西......