Search code examples
asp.netascxfindcontrol

Reference .ASCX from .ASPX dynamically via ID


I've created an .aspx page that consists of many custom .ascx controls and I'd like to create a page function that generates a tool tip for each control. I've created an interface that each .ascx control implements to create the tool tip (the function is called GetToolTipInfo(), so all I need now is a way to reference the .ascx control dynamically by it's ID.

Here is the function I'm currently trying to use...

Protected Sub SetToolTip(sender As Object, args As ToolTipUpdateEventArgs)
    Dim control As New Literal()
    Dim info As ToolTipInfo = CType(Me.FindControl(args.TargetControlID).Parent, FormFunction).GetToolTipInfo()

    control.Text = info.content
    RadToolTipManagerMain.Width = info.width
    RadToolTipManagerMain.Position = info.position

    args.UpdatePanel.ContentTemplateContainer.Controls.Clear()
    args.UpdatePanel.ContentTemplateContainer.Controls.Add(control)
End Sub

As it is, FindControl returns nothing. I could hard code each control reference into this function, but wondered if there was a more elegant way. I am also using a Master page and a Content panel if that has anything to do with it.

Thank you for any suggestions.


Solution

  • FindControl does not search within nested controls recursively. It does only find controls that's NamingContainer is the Control on that you are calling FindControl.

    Theres a reason that ASP.Net does not look into your nested controls recursively by default:

    • Performance
    • Avoiding errors
    • Reusability

    Anyway, if you want to find controls recursively, you have to loop over all controls and their child-controls. Use this Extension:

    Public Module ControlExtensions
        <Runtime.CompilerServices.Extension()>
        Public Function FindControlRecursive(ByVal rootControl As Control, ByVal controlID As String) As Control
            If rootControl.ID = controlID Then
                Return rootControl
            End If
    
            For Each controlToSearch As Control In rootControl.Controls
                Dim controlToReturn As Control = FindControlRecursive(controlToSearch, controlID)
                If controlToReturn IsNot Nothing Then
                    Return controlToReturn
                End If
            Next
            Return Nothing
        End Function
    End Module
    

    Note: This function is case-sensitive!

    You can find a control in the following way:

    Dim info = Page.FindControlRecursive(args.TargetControlID)