在自定义验证程序中访问嵌套控件

时间:2012-11-27 03:20:46

标签: asp.net

如何从自定义验证器访问嵌套在页面中多个级别的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.

这似乎完全浪费了资源。有没有更好的方法从自定义验证器访问这些控件?

2 个答案:

答案 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; 
}