我创建了几个用户控件 - 大多数包含一个Web控件(文本框,下拉列表,单选按钮等) - 以及一个或多个验证控件。关键在于将控制和验证结合在一个用户控件中。
我为这些用户控件创建了一个基类,它具有一些常用功能 - 用于单个Web控件的多个属性的setter,特别是在ascx的控件中设置的CssClass和Style。
例如,带有单个必填字段验证器的单个文本框。
基类的示例代码:
public WebControl ctrl {get; set;} //allow derived class access to this
public string CssClass
{
set { ctrl.CssClass = value; } //allow CssClass to be set in the aspx page
}
派生类的示例代码: (在构造函数或控件OnInit事件中 - 或?)
base.ctrl = txt; //tell the base class which web control to apply common properties to.
public string ErrorMessage
{
set { val.ErrorMessage = value;} //this works !
}
ascx的示例代码:
<asp:TextBox ID="txt" Cssclass="input-text-m" maxlength="50" runat="server" />
<asp:RequiredFieldValidator ID="val" runat="server" ControlToValidate="txt"
ErrorMessage="">*</asp:RequiredFieldValidator>
aspx的示例代码:
<uc:TextBox ID="ForeName" Cssclass="input-text-m" maxlength="50"
ErrorMessage="Forename" runat="server"/>
我发现的问题是,在调用基类属性setter之前,我找不到派生类设置基类Web控件引用的方法。 如果我在派生类构造函数中设置base.ctrl - 那么派生类控件引用(txt)此时仍为null。 如果我在任何控制事件中设置base.ctrl - 例如OnInit - 那么这太晚了。
到目前为止,我已经解决了这个问题,只是不使用基类,而是在用户控件类中编写属性setter代码,但这意味着重复代码,我试图避免这种情况。
有没有办法告诉基类控件我希望它在设置之前设置属性 - 或者我是以错误的方式处理事情......
答案 0 :(得分:0)
如果在任何get / set操作之前调用EnsureChildControls
并在EnsureChildControls
中包含ctrl = txt的set操作呢?对于普通的servercontrol来说,这是非常标准的做法,我认为它也适用于UserControls。
public string CssClass { set { EnsureChildControls(); ctrl.CssClass = value; } }
覆盖EnsureChildControls
,留在对base的调用中,并在调用base后设置ctrl = txt;
。
更多信息:http://msdn.microsoft.com/en-us/library/system.web.ui.control.ensurechildcontrols.aspx