2012-11-27 71 views
0

如何訪問自定義驗證程序在頁面中嵌套多個級別的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

是 - 遞歸。 – Igor

回答

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控件名稱,但這對您來說似乎很合適,因爲您有一個驗證程序驗證嵌套中繼器中的多個控件。

此解決方案使您能夠完全跳過當前的深循環 - 如果您有需要驗證的控件,它將自行註冊,否則頁面中的列表將爲空,無需檢查任何內容。這也避免了對控件名稱進行字符串比較,因爲控件不需要被搜索 - 它們會在需要時自行註冊。

+0

我不知道控件的id,因爲它們是通過多箇中繼器在aspx文件中生成的。 –

+0

@KevinWasie啊,那會比較困難。您是否在中繼器內部擁有用戶控件,或者您是直接將控件直接放置在項目模板中? – xxbbcc

+0

直接在項目模板 –

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; 
} 
+0

仍然會在系統上流失。 @xxbbcc方法可以針對流量進行擴展。謝謝。 –