我需要浏览页面上的所有控件,寻找特定的控件。我们有一堆用户控件,一个母版页,内容面板,& 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
答案 0 :(得分: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”
答案 1 :(得分: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,您可能会找到错误的控件。这非常容易出错。
除了你用他们的MasterPage硬件连接你的UserControls页面,封装和可重用性的反面。