locked
Get All Controls in a Form (children included) RRS feed

  • Question

  • Hi all

    I'm using a Language Exstension given by KereInstructor that allows to get all controls of a specific Type in a WinfForm and children Containers in the Form

    This is the code for ThextBoxes and CheckBoxes

    Public Module LanguageExtensions
    	<Runtime.CompilerServices.Extension()>
    	Public Function GetAll(ByVal control As Control, ByVal type As Type) As IEnumerable(Of Control)
            Dim controls = control.Controls.Cast(Of Control)()
            Return controls.SelectMany(Function(ctrl) GetAll(ctrl, type)) _
    				.Concat(controls).Where(Function(c) c.GetType() Is type)
    	End Function
    	<Runtime.CompilerServices.Extension()>
    	Public Function AllTextBoxes(ByVal pSender As Control) As IEnumerable(Of TextBox)
    		Return GetAll(pSender, GetType(TextBox)).OfType(Of TextBox)
    	End Function
    	<Runtime.CompilerServices.Extension()>
    	Public Function AllCheckBoxes(ByVal pSender As Control) As IEnumerable(Of CheckBox)
    		Return GetAll(pSender, GetType(CheckBox)).OfType(Of CheckBox)
    	End Function


    and this is the application for AllTextBoxes

    Public Sub GetAllTB() Me.AllTextBoxes.ToList.ForEach( Sub(tb) ' DO SOMETHING with each TextBox End Sub)

    end Sub

    This is fine and it works perfectly.

    Now I'm trying to use the similar code to get ALL Controls in the form indipendetly from the type

    this is the code I used

      <Runtime.CompilerServices.Extension()>
        Public Function AllControl(ByVal pSender As Control) As IEnumerable(Of Control)
            Return GetAll(pSender, GetType(Control)).OfType(Of Control)
        End Function
    

    But id doesn't work. So How to get all Controls and child controls in a Form ?


    Tuesday, December 18, 2018 8:09 PM

Answers

  • Hello,

    You didn't follow what I did, the code module needs to be public

    Public Module Extensions
        <Runtime.CompilerServices.Extension>
        Public Iterator Function Descendants(Of T As Class)(ByVal control As Control) As IEnumerable(Of T)
            For Each child As Control In control.Controls
                Dim thisControl As T = TryCast(child, T)
                If thisControl IsNot Nothing Then
                    Yield CType(thisControl, T)
                End If
    
                If child.HasChildren Then
                    For Each descendant As T In Descendants(Of T)(child)
                        Yield descendant
                    Next
                End If
            Next
        End Function
        <Runtime.CompilerServices.Extension>
        Public Function DescendantsOfTextBoxes(ByVal sender As Control) As List(Of TextBox)
            Return sender.Descendants(Of TextBox)().ToList()
        End Function
    End Module
    
    
    


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    • Proposed as answer by dbasnett Wednesday, December 19, 2018 5:02 PM
    • Marked as answer by Claudio111 Thursday, December 20, 2018 2:36 PM
    Wednesday, December 19, 2018 10:37 AM

All replies

  • Hello,

    I've got a new version

    Public Module FormExtensions
        <Runtime.CompilerServices.Extension>
        Public Iterator Function Descendants(Of T As Class)(control As Control) As IEnumerable(Of T)
            For Each child As Control In control.Controls
                Dim thisControl As T = TryCast(child, T)
                If thisControl IsNot Nothing Then
                    Yield CType(thisControl, T)
                End If
    
                If child.HasChildren Then
                    For Each descendant As T In child.Descendants(Of T)()
                        Yield descendant
                    Next descendant
                End If
            Next child
        End Function
    
    End Module

    Take a test ride, in this case in a form and no need to set a parent as Me is implied, othterwise say we can all controls on say Panel1 Panel1.Descendant....

    Descendants(Of Control).
        ToList().
        ForEach(Sub(ctrl) Console.WriteLine($"Name: {ctrl.Name}"))

    Or

    Dim allControls as List(Of Control) = Descendants(Of Control).ToList()
    Here is my original code (but in C#).


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites


    Tuesday, December 18, 2018 9:10 PM
  • Hi Karen

    Sorry but I'm not able to use it

    I put the following in a Module

    Imports System.Windows.Forms
    
    Module ModListAllControl
        <Runtime.CompilerServices.Extension>
        Public Iterator Function Descendants(Of T As Class)(ByVal control As Control) As IEnumerable(Of T)
            For Each child As Control In control.Controls
                Dim thisControl As T = TryCast(child, T)
    
                If thisControl IsNot Nothing Then
                    Yield CType(thisControl, T)
                End If
    
                If child.HasChildren Then
    
                    For Each descendant As T In Descendants(Of T)(child)
                        Yield descendant
                    Next
                End If
            Next
        End Function
        <Runtime.CompilerServices.Extension()>
        Public Function DescendantsOfTextBoxes(ByVal sender As Control) As List(Of TextBox)
            Return sender.Descendants(Of TextBox)().ToList()
        End Function
    End Module

    Then I try to use the function in my Form

     Public Sub Prova()
            Dim allTB As List(Of TextBox) = DescendantsOfTextBoxes(Of TextBox).ToList()
        End Sub

    But I get error : ....DescendastOfTextBoxes .... is not accesible in this contest because it is "Public".

    I'M not able with Exstension so what is my mistake ?


    • Edited by Claudio111 Wednesday, December 19, 2018 8:59 AM
    Wednesday, December 19, 2018 8:57 AM
  • Hello,

    You didn't follow what I did, the code module needs to be public

    Public Module Extensions
        <Runtime.CompilerServices.Extension>
        Public Iterator Function Descendants(Of T As Class)(ByVal control As Control) As IEnumerable(Of T)
            For Each child As Control In control.Controls
                Dim thisControl As T = TryCast(child, T)
                If thisControl IsNot Nothing Then
                    Yield CType(thisControl, T)
                End If
    
                If child.HasChildren Then
                    For Each descendant As T In Descendants(Of T)(child)
                        Yield descendant
                    Next
                End If
            Next
        End Function
        <Runtime.CompilerServices.Extension>
        Public Function DescendantsOfTextBoxes(ByVal sender As Control) As List(Of TextBox)
            Return sender.Descendants(Of TextBox)().ToList()
        End Function
    End Module
    
    
    


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    • Proposed as answer by dbasnett Wednesday, December 19, 2018 5:02 PM
    • Marked as answer by Claudio111 Thursday, December 20, 2018 2:36 PM
    Wednesday, December 19, 2018 10:37 AM
  • ops

    It works fine, it is what i needed.

    Thank you Karen


    Wednesday, December 19, 2018 3:19 PM
  • ops

    It works fine, it is what i needed.

    Thank you Karen


    Great, don't forget to mark this thread as answered for other to know you have a resolution.

    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Wednesday, December 19, 2018 3:22 PM