不确定这是否适用于 .Net 的所有版本(我认为是 2.0 或更高版本),但有一个名为 CreateChildControls 的方法实际上并不是生命周期的一部分,它基本上在任何时候调用 EnsureChildControls 方法。默认情况下,如果它不是回发,它会在 PreRender 之前调用。所以基本上你的代码看起来像这样:
public class SomeControl : WebControl, INamingContainer
{
private TextBox someTextBox;
protected override void CreateChildControls()
{
base.CreateChildControls();
someTextBox= new TextBox();
someTextBox.ID = "tbxMain";
Controls.Add(textboxToCheck);
}
}
现在不应该的部分是,除非您调用 EnsureChildControls,否则在 ViewState 负载填充控件上的公共属性之前,您不能 100% 确定控件存在。这是什么意思?好吧,取之前的代码并为 CssClass 添加一个属性:
public class SomeControl : WebControl, INamingContainer
{
private TextBox someTextBox;
protected override void CreateChildControls()
{
base.CreateChildControls();
someTextBox= new TextBox();
someTextBox.ID = "tbxMain";
Controls.Add(textboxToCheck);
}
public String CssClass { get; set; }
}
在 CreateChildControls 你不会想要这个:
someTextBox.CssClass = CssClass;
由于尚无法确定控件是否存在。有几种方法可以处理这个问题:
公共字符串 CssClass { 获取 { EnsureChildControls(); 返回一些Textbox.CssClass;}
set
{
EnsureChildControls();
someTextbox.CssClass = value;
}
在此示例中,我正在调用 EnsureChildControls(假设您在 CreateChildControls 方法中的文本框上设置 CssValue)并从文本框中设置或获取。
另一种方法是将依赖于控件公共属性的任何内容放在 OnPreRender 方法中:
protected override void OnPreRender(EventArgs e)
{
someTextbox.CssClass = CssClass;
}
从而避免了在 ViewState 加载期间担心属性已经被填充的混乱。
一注:
INamingContainer 的使用可能很重要。基本上,所做的只是确保父控件上的控件具有在页面上唯一的 id,方法是将父控件的名称(可能更多)应用于 id。基本上,如果父 ID 是 Parent 而子控件 ID 是 Child,则 ID 可能会显示为 Parent_Child。这将解决 ViewState 无法正确填充属性或根本不填充属性的问题。