如何从自定义验证器访问嵌套在页面中多个级别的asp.net控件?
具体来说,我正在生成占位符内的下拉列表,占位符位于转发器内,转发器位于另一个转发器内,位于另一个占位符内。
我需要访问所有下拉框的选定值以进行相互比较。
我目前的解决方案是遍历每个控件中的所有控件,直到我深入到访问下拉列表:
For Each g As Control In sender.Parent.Controls
If g.GetType().ToString.Equals("System.Web.UI.WebControls.Repeater") Then
For Each k As Control In g.Controls
If k.GetType().ToString.Equals("System.Web.UI.WebControls.RepeaterItem") Then
For Each l As Control In k.Controls
If l.GetType().ToString.Equals("System.Web.UI.WebControls.Repeater") Then
For Each p As Control In l.Controls
If p.GetType().ToString.Equals("System.Web.UI.WebControls.RepeaterItem") Then
For Each n As Control In p.Controls
If n.GetType().ToString.Equals("System.Web.UI.WebControls.PlaceHolder") Then
For Each c As Control In n.Controls
If c.GetType().ToString.Equals("System.Web.UI.WebControls.DropDownList") Then
'Add the dropdownlist to an array so that I can use it after all drop down lists have been added for validation.
这似乎完全浪费了资源。有没有更好的方法从自定义验证器访问这些控件?
答案 0 :(得分:0)
我相信你可以使用$
连接容器名来访问嵌套控件;像这样的东西:
ControlToValidate="panel1$usercontrol1$otherusercontrol$textbox1"
这会导致验证程序执行内部FindControl()
调用,这有点贵,因此您应该谨慎使用此方法。
通常,在其他容器中访问深层嵌套控件并不是一个好主意。您应该将这些控件视为页面/控件的私有成员,而不是以这种方式访问它们。如果真的必须,只能使用上述方法。
编辑:这可能不是完美的解决方案,但我会这样做。创建一个新的DropDownListX控件(从DropDownList派生),该控件抓取页面并检查页面是否实现了您创建的新自定义接口。此接口可用于向页面注册控件,然后验证器可以浏览此列表并验证每个已注册的控件。类似的东西:
interface IValidationProvider
{
void RegisterForValidation ( Control oCtrl );
}
您的页面应该实现此界面。然后在你的新DropDownListX控件中:
protected override void OnLoad ( EventArgs e )
{
IValidationProvider oPage = Page as IValidationProvider;
if ( oPage != null )
oPage.RegisterForValidation ( this );
}
然后在页面中,当验证发生时,您可以浏览验证列表中的控件列表并逐个验证它们。您的自定义验证器不会有一个ControlToValidate
控件名称,但这似乎适合您,因为您有1个验证器可验证嵌套转发器中的多个控件。
此解决方案使您能够完全跳过当前的深循环 - 如果您有需要验证的控件,它将自行注册,否则页面中的列表将为空,无需检查任何内容。这也避免了对控件名称进行字符串比较,因为不需要搜索控件 - 他们在需要时自行注册。
答案 1 :(得分:0)
你是否尝试过递归控制?
private Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
{
return root;
}
foreach (Control c in root.Controls)
{
Control t = FindControlRecursive(c, id);
if (t != null)
{
return t;
}
}
return null;
}