2011-12-12 61 views
0

我需要瀏覽頁面上的所有控件,尋找特定的控件。我們有一堆用戶控件,一個母版頁,內容面板,& c。如何從遞歸函數中返回對象?

基本思想很簡單,但一旦找到我想要的控件,說五個「圖層」,控件只返回一個級別。

我知道我可以做一些俗氣的事情,比如有一個私人變量,並將控制權分配給兔子洞中的那個,但是我認爲必須有一個更正式的方法來做到這一點。

另外,這就是所謂的尾遞歸?

我們使用3.5框架。

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
    Dim c As Control = getNamedControl(Page, "tb") 
End Sub 


Private Function getNamedControl(ByVal root As Control, ByVal theTarget As String) As Control 
    If root.Controls.Count < 1 Then 
     If Not IsNothing(root.ID) Then 
      If root.ID = theTarget Then 
       Return root 
      End If 
     End If 
    Else 
     For Each c As Control In root.Controls 
      If c.ID = theTarget Then 
       Return c 
      Else 
       getNamedControl(c, theTarget) 
      End If 
     Next 
    End If 
End Function 

回答

1
Public Module WebControlExtensions 
    ' Can be used to find controls recursively that won't be found via Page.FindControl 
    ' because they are nested in other NamingContainers 
    ' Example: Dim ctrl = Page.FindControlRecursive("tb") ' 
    <Runtime.CompilerServices.Extension()> 
    Public Function FindControlRecursive(ByVal rootControl As Web.UI.Control, ByVal controlID As String) As Web.UI.Control 
     If rootControl.ID = controlID Then 
      Return rootControl 
     End If 

     For Each controlToSearch As Web.UI.Control In rootControl.Controls 
      Dim controlToReturn As Web.UI.Control = FindControlRecursive(controlToSearch, controlID) 
      If controlToReturn IsNot Nothing Then 
       Return controlToReturn 
      End If 
     Next 
     Return Nothing 
    End Function 
End Module 

該函數將立即返回控制,當它被發現。

我們有一大堆的用戶控件,一個母版,內容面板的...

你確定它的使用遞歸函數來找到你的控件是一個好主意?特別是如果您在MasterPage的ContentPages的頁面中使用具有相同ID的UserControl,您可能會發現錯誤的控件。這是非常容易出錯的。

除了你的UserControls與他們的頁面與他們的MasterPage硬連線外,封裝和可重用性相反。

+0

我只是喝咖啡,我的解決方案是在辦公室,所以我還無法消化。然而,感謝您的回覆,甚至更多的是關於這是否是最佳解決方案的深思熟慮的問題。我覺得我總是會有更多的學習 - 設計方法和考慮是無限的,而語言和技術雖然廣泛,但在某些方面有限。 – aape

+0

我必須承認,我從來不需要使用我自己的遞歸函數。您應該首先了解控件如何相互嵌套,瞭解控件的[NamingContainers](http://msdn.microsoft.com/zh-cn/library/system.web.ui.control.namingcontainer.aspx)是什麼。然後你知道如何以正確的方式(直接)獲得對控件的引用。然後學習[用戶控件應該如何與他們的頁面進行通信(反之亦然)](http://stackoverflow.com/a/5510150/284240),頁面與他們的主頁面等。 –

1
If c.ID = theTarget Then 
     Return c 
    Else 
     getNamedControl(c, theTarget) 
    End If 

變爲:

If c.ID = theTarget Then 
     Return c 
    Else 
     Dim d as Control 
     d = getNamedControl(c, theTarget) 
     If Not IsNothing(d) Then 
      return d 
     End If 
    End If 

然後就結束函數之前:

return Null 

編輯:

假設返回值進行檢查,這是不是尾遞歸。

看到:http://en.wikipedia.org/wiki/Tail_call 搜索 「foo3」

+0

非常感謝您的回覆和代碼。 – aape