Home > Mobile >  Set listbox content on form1 from class at startup in VB.net
Set listbox content on form1 from class at startup in VB.net

Time:06-06

I have the following situation:

In form1's constructor, I create an instance of a class. This class's constructor performs some actions and is then to populate form1's listbox with said data.

When I run the code, I get an exception that a loop occured and that I should use me, not form1 but the listbox is not part of the class, so I can only connect to form1.listbox1.

If I add a button and put the code there, all works fine. How can I populate the listbox during program startup?

Here's an example of my code:

Form1:

Public Class Form1
    Public MyClass1 As New MyClass

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    End Sub
End Class

MyClass:

Public Class MyClass
    Public MyList as new Listbox
    Public Sub New()
        'Constructor. 
        Me.MyList.AddItem ("Test")
        Me.UpdateDebugView()
    End Sub

    Public Sub UpdateDebugView()
        Form1.lTodoList = Me.MyList
    End Sub


End Class

Exception thrown (translated to english):
The form referenced to itself while attempting to make a defaultitem, that lead to an endless loop. Reference inside the constructor of the form to the form using Me.

System.InvalidOperationException

CodePudding user response:

When you hold a reference to something, you can access its members, but it shouldn't access yours (in most cases). But you can communicate backwards with events.

Declare MyClass1 as WithEvents in the Form, and you can add a designer event handler to the code (alternatively, you can add the handler dynamically but I have done the prior below). Raise the event instead of trying to set something on the Form.

Public Class Form1
    Public WithEvents MyClass1 As New MyClass

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    End Sub

    Private Sub MyClass1_ToDo() Handles MyClass1.ToDo
        Me.lToDoList = MyClass.MyList
    End Sub
End Class

Public Class MyClass
    Public MyList as new Listbox
    Public Sub New()
        'Constructor. 
        Me.MyList.AddItem ("Test")
        Me.UpdateDebugView()
    End Sub

    Public Sub UpdateDebugView()
        RaiseEvent ToDo
    End Sub

    Public Event ToDo()

End Class

I would normally pass back the state to the event handler, but I didn't feel good about passing a ListBox. Maybe you can expose a data structure instead of a UI control to keep the UI on the UI, and out of the class. This should work for you though

CodePudding user response:

The problem is the location of creating the MyClass object.

It is created at the beginning of class creation before anything else runs. You can fix it by moving the creation of secondary class levels to the form_load sub as follows:

Public Class Form1
    Public MyClass1

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Me.MyClass1 = new MyClass

    End Sub
End Class

This ensures that the form loads fully before creating other classes and as such, they can now refer to items on Form1.

  • Related