List of all Controls

fabiocrj

Member
Joined
Mar 15, 2011
Messages
10
Programming Experience
Beginner
Hi all,

I don´t know if this is the right area. Please sorry if not.
Well, first of all, thanx for your attention. I´ve searched the whole web (at last where google can see) for a solution, but i just can´t find.
The problem is the following: I want a list of all controlls in my project, not only on open forms. The reason is that i want to make an access control, and the admin will set which buttons each users can use.

what i´ve got so far is:

Public Sub getallforms(ByVal sender As Object)
Dim Forms As New List(Of Form)()
Dim formType As Type = Type.GetType("System.Windows.Forms.Form")
For Each t As Type In sender.GetType().Assembly.GetTypes()
If UCase(t.BaseType.ToString) = "SYSTEM.WINDOWS.FORMS.FORM" Then
MsgBox(t.Name)
End If
Next
End Sub

This shows me all forms in project. But i cant access their controls. to you have any ideia of how doing what i want?
Thank you very much!
 

Solitaire

Well-known member
Joined
Jun 28, 2004
Messages
465
Location
New York
Programming Experience
10+
You can try this. The first sample code below will list the names of all your controls on the main form and in any containers on the form inside a listbox. Your control names should include the descriptive prefix that will identify the type of control. The second sample will display the control type but not the name. If you wish, you can combine the two to display both the type and the name of the control as in the third sample.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ListBox1.Items.Clear()
For Each ctl As Control In Controls
ListBox1.Items.Add(ctl.Name)
For Each child As Control In ctl.Controls
ListBox1.Items.Add("Contains: " & child.Name)
Next child
Next ctl
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim ctltype As Type, typename As String
ListBox1.Items.Clear()
For Each ctl As Control In Controls
ctltype = ctl.GetType
typename = ctltype.ToString
TypeName = TypeName.Substring(21)
ListBox1.Items.Add(TypeName.ToString)
For Each child As Control In ctl.Controls
ctltype = child.GetType
typename = ctltype.ToString
typename = typename.Substring(21)
ListBox1.Items.Add("Contains: " & typename.ToString)
Next child
Next ctl
End Sub

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim ctltype As Type, typename As String
ListBox1.Items.Clear()
For Each ctl As Control In Controls
ctltype = ctl.GetType
typename = ctltype.ToString
typename = typename.Substring(21) & ": " & ctl.Name
ListBox1.Items.Add(typename.ToString)
For Each child As Control In ctl.Controls
ctltype = child.GetType
typename = ctltype.ToString
typename = typename.Substring(21) & ": " & child.Name
ListBox1.Items.Add("Contains: " & typename.ToString)
Next child
Next ct
 
Last edited:

fabiocrj

Member
Joined
Mar 15, 2011
Messages
10
Programming Experience
Beginner
ok, thanks for you attention! that´[ s almost what i ´m looking for... but it wont list only the controls in open foms? I need something to show me every form, even the closed ones...
Thank you =]
 

Solitaire

Well-known member
Joined
Jun 28, 2004
Messages
465
Location
New York
Programming Experience
10+
I think what you may have to do is temporarily open the forms to read them, and then close them again.
 

fabiocrj

Member
Joined
Mar 15, 2011
Messages
10
Programming Experience
Beginner
Hi,

Yeah, this is the only way i can think now... But how can i open all forms? I can list their names with the code i posted, but i don´t know how to open then by their name...
And there is no way of listing all controls by something like (i know its wrong):

If UCase(t.BaseType.ToString) = "SYSTEM.WINDOWS.FORMS.FORM.CONTROL" ?

Thank You very much
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,331
Location
Norway
Programming Experience
10+
I agree with Solitaire the best option is using a form instance and iterate the Controls collections. Since these are hierarchal using a recursive method is easiest. I prepared a short example as well and use the TreeView control for display since this is how the controls are layed out on a form. First the recursive method:
Code:
Private Sub ControlsTree(node As TreeNode, controls As Control.ControlCollection)
    For Each ctrl As Control In controls
        If ctrl.Name <> String.Empty Then
            Dim child = node.Nodes.Add(ctrl.GetType.Name & ": " & ctrl.Name)
            ControlsTree(child, ctrl.Controls)
        End If
    Next
End Sub
Then looping and adding each form, using reflection on My.Forms collection:
Code:
For Each formprop In My.Forms.GetType.GetProperties
    Dim node = Me.FormsTreeView.Nodes.Add(formprop.Name)
    Dim frm As Form = CType(formprop.GetValue(My.Forms, Nothing), Form)
    ControlsTree(node, frm.Controls)
Next
Playing with lambas, this is an alternative for ControlsTree method that can be used:
Code:
Private Sub ControlsTree(node As TreeNode, controls As Control.ControlCollection)
    Dim Display = Function(c As Control) c.GetType.Name & ": " & c.Name        
    Dim HasName = Function(c As Control) c.Name <> String.Empty
    Dim AddRecursive = Sub(c As Control) ControlsTree(node.Nodes.Add(Display(c)), c.Controls)

    controls.OfType(Of Control).Where(HasName).ToList.ForEach(AddRecursive)
End Sub
 

fabiocrj

Member
Joined
Mar 15, 2011
Messages
10
Programming Experience
Beginner
Hey, man

thats EXACTLY what i was looking for... THANK YOU VERY MUCH...
Just to show my progress before you, here is what i had got:

Code:
        Dim asm = System.Reflection.Assembly.GetExecutingAssembly
        Dim myTypes As Type() = asm.GetTypes()
        Dim frm As Form
        Dim s As String
        Dim x As Integer = 0
        For Each t As Type In myTypes
            If t.IsSubclassOf(GetType(System.Windows.Forms.Form)) AndAlso t.Name <> Me.Name Then
                frm = CType(Activator.CreateInstance(t), Form)
                s = s & UCase(frm.Name)
                nomesControles(frm, s)
                x += 1
            End If
        Next
        MsgBox(s)

Sub nomesControles(ByVal C As Control, ByRef s As String, ByVal p As String)

        Dim Ctrl As Control 'Declare generic control object
        s = s & vbNewLine
        For Each Ctrl In C.Controls
            If TypeName(Ctrl) = "Button" Then s = s & p & Ctrl.Name & vbNewLine
            If Ctrl.Controls.Count > 1 Then 'Check for container control
                s = s & p & UCase(Ctrl.Name)
                nomesControles(Ctrl)
            End If
        Next Ctrl
        s = s & vbNewLine
    End Sub
 

fabiocrj

Member
Joined
Mar 15, 2011
Messages
10
Programming Experience
Beginner
Additionally, there is any way of identifying each control uniquely? Like an control ID, which remains the same even if I rename the control or its properties?
Grateful
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,331
Location
Norway
Programming Experience
10+
For controls added in designer the Name property serves that purpose. For example will the designer services ensure each control is given a Name, and that the Name is unique.
 

fabiocrj

Member
Joined
Mar 15, 2011
Messages
10
Programming Experience
Beginner
Ok, that´s what i´m using right now...
just to explain why i am doing, i want to make a user control, with possibilities to enable/disable/hide each form, button, textbox, etc., So then i can fully manage each group of users. It´s an inventory system, and each group of users can add only the type of information they are allowed to, other can only view information, etc...
I ´ll have 2 columns in my DB for this:

table1: relation between users and groups (userID - groupId), that will store which users are in each group
table2: relation of allowed controls per group (example):
groupID - Controls
1 - btnX
1 - btnY
3 - txtBoxX
8 - txtBoxY
1 - txtBoxX

So, if a user is in group 1, when he logs in and open the form, only btnX, btnY and txtBoxX will be enabled. Other controls will be not enabled
 
Top Bottom