0

I am trying to create a general function in VB.NET that can dynamically create a form object (label , button etc.) and this object can be pin the form or container . My problem is i am unable to pass the control object type to the function when calling it. Visual studio gives error.

Private Function AddnewObject(newObject As Integer, ContainerObject As Object, ByRef Objectn As Control) As System.Windows.Forms.Control`
    ContainerObject.Controls.Add(Objectn)
    Objectn.Top = 560 + (newObject * 27)
    Objectn.Left = 100
    Objectn.Text = Objectn.ToString & newObject.ToString
    newObject += 1 ' useless in this context 
    Return Objectn
End Function

when trying to call it like this :

AddnewObject(concounter, TableLayoutPanel1, Label)

i get error

BC30109 'Label' is a class type and cannot be used as an expression.

I tried to change the type of objectn but can't figure the correct one/way to use

1
  • The generic version is better, but in the alternative, you would need an additional argument to the function of type Type to indicate what control type to instantiate. Then, instead of Label, you would use GetType(Label) and pass the instance to receive the new control (if needed) in the ByRef argument. Commented Aug 16, 2022 at 17:27

1 Answer 1

1

You can pass a type as parameter with generic type parameters (the (Of T) part in front of the normal parameter list). Normal Sub or Function parameters can be only values, not types (though they can be of type System.Type).

I suggest to change the function like this

Private conCounter As Integer = 1

Private Function AddNewControl(Of T As {Control, New})(controls As Control.ControlCollection) As T
    Dim newControl As T = New T()
    controls.Add(newControl)
    With newControl
        .Top = 560 + (conCounter * 27)
        .Left = 100
        .Name = GetType(T).Name & conCounter
    End With
    conCounter += 1
    Return newControl
End Function

and to call it like this

Dim newControl = AddNewControl(Of Label)(TableLayoutPanel1.Controls)

Explanation:

  • The type of the control to be created is passed as generic type parameter. The type constraint {Control, New} ensures that only control types are passed and that they have a default constructor (which is always the case for Controls).

  • I am using concrete types instead of Object. Use Option Strict On to create better quality code.

  • Since not all controls used as container object inherit from ContainerControl (e.g., TableLayoutPanel does not), I have chosen to pass the ControlCollection of the container object to this function instead.

  • The counter needs not to be passed as parameter if it is in the same class (or module)

This function does return the new control as function value. If this is not required, you can also turn it into a Sub instead.

Private Sub AddNewControl(Of T As {Control, New})(controls As Control.ControlCollection)
    Dim newControl As T = New T()
    controls.Add(newControl)
    With newControl
        .Top = 560 + (conCounter * 27)
        .Left = 100
        .Name = GetType(T).Name & conCounter
    End With
    conCounter += 1
End Sub

And call with

AddNewControl(Of Label)(TableLayoutPanel1.Controls)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.