Results 1 to 12 of 12

Thread: List (of ) and Listbox

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2010
    Posts
    402

    List (of ) and Listbox

    I curretly have the following code (proof of concept) that displays the contents of a List of Strings in a List box.

    Can someone please advise if this is the correct way of doing this, or can it be simplified. Note Form 2 contains Listbox1. Also i was not keen on having aDatalist defined as Friend as the modules can not then be tested in isolation.

    Code:
      Friend aDataList As New List(Of String)
        Private Sub TestToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles TestToolStripMenuItem.Click
            aDataList.Add("Item 1")
            aDataList.Add("Item 2")
            aDataList.Add("Item 3")
            aDataList.Add("Item 4")
        End Sub
    
        Private Sub TestDisplayToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles TestDisplayToolStripMenuItem.Click
            For Each item As String In aDataList
                Form2.ListBox1.Items.Add(item)
            Next
            Form2.ShowDialog()
        End Sub
    End Class

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,897

    Re: List (of ) and Listbox

    I'm not sure what your concern is with friend. Testing it in isolation shouldn't be impacted by that.

    In general, you should get away from using the default instance of forms. Default instances don't necessarily harm anything, but they have caused so much confusion over the years that it would be a good practice to mostly avoid them.

    If you have a Form2 in your project (a better name would be better, but this is mostly just an example, so the name is fine), that is a type, not an object. What VB does is quietly add a line that looks something like this:
    Code:
    Public Form2 As New Form2
    In other words, it is quietly making an instance with the same name as the class type. What is actually done is not this, but more efficient than this. For example, the object isn't created if it is never used, so that line of code doesn't exist unless you start doing something like Form2.ListBox1.Items.Add(). If you don't use it, it never gets created. If you DO use it, then it gets created. That's not a big deal, so long as you know that you have an actual instance that happens to share the name of the type.

    This has a couple consequences. If the form has no default constructor (one that takes no arguments), then the default instance can't be created, and writing Form2.ShowDialog would give you a compile time error. This can confuse people. Another issue is that the default instances are thread local, which isn't an issue if you aren't doing threading, but causes further confusion if you are.

    What would be better would be:
    Code:
           Dim yourForm2 = New Form2
            For Each item As String In aDataList
                yourForm2 .ListBox1.Items.Add(item)
            Next
            yourForm2 .ShowDialog()
    Or, better yet:
    Code:
    Using yourForm2 As New Form2
            For Each item As String In aDataList
                yourForm2 .ListBox1.Items.Add(item)
            Next
            yourForm2 .ShowDialog()
    End Using
    The latter will properly dispose of the form, which probably means nothing at all in this case.
    My usual boring signature: Nothing

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2010
    Posts
    402

    Re: List (of ) and Listbox

    That’s great thanks, it was only a proof of concept code and I was keen to see if I was correctly displaying a list of strings in a list box. I would normally code form2 as new Form2.

    I did not know if there was a simpler way to add all the items to the list box, without looping through them individually.
    Last edited by Signalman; Nov 29th, 2023 at 05:05 PM.

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,230

    Re: List (of ) and Listbox

    You really shouldn't be referring to a control on a form from another form at all. You should be passing the list into the other form and then the form should be referring to its own control.

    As for populating the control, if you want to add multiple items to a list of any sort, you should choose to call AddRange once rather than Add multiple times. In the case of a control like a ListBox, you also have the option of using data binding, which would mean assigning the list to the DataSource property.

  5. #5
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,452

    Re: List (of ) and Listbox

    Code:
    Public Class Form2
    
        Public Sub New(ByVal items() As String)
            ListBox1.Items.AddRange(items)
        End Sub
    
    End Class
    Code:
    Dim frm As New Form2(aDataList)
    Frm.Show

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,230

    Re: List (of ) and Listbox

    Quote Originally Posted by .paul. View Post
    Code:
    Public Class Form2
    
        Public Sub New(ByVal items() As String)
            ListBox1.Items.AddRange(items)
        End Sub
    
    End Class
    Code:
    Dim frm As New Form2(aDataList)
    Frm.Show
    Be aware that aDataList is a List(Of String) in the original code but is being treated as an array here. You'd need to call ToArray at some point, because AddRange expects an array in this case. Some AddRange methods will accept an IEnumerable.

  7. #7
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,452

    Re: List (of ) and Listbox

    Quote Originally Posted by .paul. View Post
    Code:
    Public Class Form2
    
        Public Sub New(ByVal items() As String)
            ListBox1.Items.AddRange(items)
        End Sub
    
    End Class
    Code:
    Dim frm As New Form2(aDataList)
    Frm.Show
    Quote Originally Posted by jmcilhinney View Post
    Be aware that aDataList is a List(Of String) in the original code but is being treated as an array here. You'd need to call ToArray at some point, because AddRange expects an array in this case. Some AddRange methods will accept an IEnumerable.
    Just change the initialising code...

    Code:
    Dim frm As New Form2(aDataList.ToArray)
    Frm.Show

  8. #8

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2010
    Posts
    402

    Re: List (of ) and Listbox

    Thts great, and certainly makes the coding more simple, however when I run the code, I am getting an error :- Object reference is not set to an instance of an object

    Code:
    Public Class Form2
    
        Public Sub New(ByVal items() As String)
            ListBox1.Items.AddRange(items)  <---Errror 'Object reference is not set 
        End Sub                                       to an instance of an object'
    
    End Class

  9. #9
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,452

    Re: List (of ) and Listbox

    Code:
    Public Sub New(ByVal items() As String)
        InitializeComponent
        ListBox1.Items.AddRange(items)  <---Errror 'Object reference is not set 
    End Sub

  10. #10
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,230

    Re: List (of ) and Listbox

    Quote Originally Posted by .paul. View Post
    Code:
    Public Sub New(ByVal items() As String)
        InitializeComponent
        ListBox1.Items.AddRange(items)  <---Errror 'Object reference is not set 
    End Sub
    By way of explanation, you always need to call InitializeComponent because it's that method that executes the code generated by your actions in the designer. It creates and configures all your controls. If you don't do that then there are no controls, so all the fields that are supposed to refer to them will be Nothing. You need to either have a parameterless constructor that makes that call and then call that in your other constructor:
    Code:
    Public Sub New()
        InitializeComponent()
    End Sub
    
    Public Sub New(ByVal items() As String)
        Me.New()
    
        ListBox1.Items.AddRange(items)
    End Sub
    or else do as .paul. showed and call it directly in your constructor with parameters. What I tend to do when writing constructors is write it without parameters initially, in which case VS will add the InitializeComponent call automatically, and then add the parameter(s) and additional code afterwards.

  11. #11
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,897

    Re: List (of ) and Listbox

    InitializeComponents() isn't a mystery, either. You can find it in the .designer.vb file associated with the form. Normally, you shouldn't do anything to that file yourself, as anything you do could be wiped away automatically. The IDE will re-write that file as needed. Still, it's nothing special, just code like any other code.
    My usual boring signature: Nothing

  12. #12
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,230

    Re: List (of ) and Listbox

    Quote Originally Posted by Shaggy Hiker View Post
    InitializeComponents() isn't a mystery, either. You can find it in the .designer.vb file associated with the form. Normally, you shouldn't do anything to that file yourself, as anything you do could be wiped away automatically. The IDE will re-write that file as needed. Still, it's nothing special, just code like any other code.
    Indeed. You can test for yourself by making a legitimate change to that file and see it reflected in the designer and vice versa. If the designer becomes corrupted for whatever reason, something you need to make manual changes to that method to fix it. You'll need to click the Show All Files button in the Solution Explorer for the designer code file to be visible when you expand the node for your form. You can also open it by clicking on the name of a control in the user code file and selecting Go To Definition, because those fields are declared in the designer code file.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width