0

I am making a dvd database system in windows form and trying to display the dvd's entered by a user. Then display the Title, Director and Genre in 3 separate listBoxes.

When the user enters the information through 3 separate text boxes, the information is stored in a structure I made called TDvd. This means I can call for example dvd.Title or dvd.Director. I also use the variable index to add this information to an array I made called Dvd(100) (just a random number I used to test).

Here is the code I currently have for adding the items to the ListBox:

For i = 1 To noOfAddedDvds
    lstTitle.Items.Add(dvd(i).Title)
    lstDirector.Items.Add(dvd(i).Director)
    lstGenre.Items.Add(dvd(i).Genre)
Next

The variable NoOfDvdsAdded is just a way of keeping track of the number of dvd's the user has already entered.

I run this and enter the Title, Director and Genre, but when I try and display this information across the 3 listboxes, I get the error:

An unhandled exception of type 'System.ArgumentNullException' occurred in System.Windows.Forms.dll

Public Class Form1
Structure TDvd
    Dim Title As String
    Dim Director As String
    Dim Genre As String
End Structure
Dim dvd(100) As TDvd
Dim index As Integer = 0
Dim noOfAddedDvds As Integer

Private Sub btnAddToDatabase_Click(sender As Object, e As EventArgs) Handles btnAddToDatabase.Click
    If txtDirector.Text <> "" Or txtGenre.Text <> "" Or txtTitle.Text <> "" Then
        txtTitle.Text = dvd(index).Title
        txtDirector.Text = dvd(index).Director
        txtGenre.Text = dvd(index).Genre
        index += 1
        noOfAddedDvds += 1
    End If
    End Sub

Private Sub btnDisplayDatabase_Click(sender As Object, e As EventArgs) Handles btnDisplayDatabase.Click
    Dim i As Integer
    For i = 0 To noOfAddedDvds
        MessageBox.Show(index & ", " & i)
        lstTitle.Items.Add(dvd(i).Title)
        lstDirector.Items.Add(dvd(i).Director)
        lstGenre.Items.Add(dvd(i).Genre)
        MessageBox.Show(index & ", " & i)
    Next

End Sub

End Class

6
  • 1
    what line does it happen on and what is the value of i at that time? Arrays are 0 based, so that should probably be for i = 0 to noOfAddedDvds - 1. It sounds like you are passing nulls to the listbox by referencing non initialized elements. a List(of DVDInfo) would work better than an array and not allow problems like this Commented Jul 15, 2014 at 12:45
  • Happens of the "lstTitle.Items.Add(dvd(i)Title)" line, and I had set index to = 1 when I declared it earlier. I can upload all the code if that would help? Commented Jul 15, 2014 at 12:47
  • That would help, yes, Commented Jul 15, 2014 at 12:48
  • when i gets to noOfAddedDvds it is pointing to an element with nothing there (you never said what the debugger reported the value of i to be). Use for i = 0 to noOfAddedDvds - 1. I'd sort of expect a NullReference exception since there is nothing at the index of noOfAddedDvds, but I guess ListBox is speaking up first. Commented Jul 15, 2014 at 13:00
  • I tried that and also put in a messageBox.show(index & ", " & i) to look at to find the problem. They were returning 1, 0, but that would be expected since I incremented index by 1 at the end of the btnAddToDatabase, this means whilst adding the film information, it should have been entering to dvd(0), and when displaying the i is set to 0 and yet it still shows me the same error. Thanks for the help so far by the way :) Commented Jul 15, 2014 at 13:11

3 Answers 3

1

According to the documentation, an ArgumentNullException is thrown by the Add() method if the argument passed to it is null. (Or Nothing in VB.) So one of these is Nothing at runtime:

dvd(i).Title
dvd(i).Director
dvd(i).Genre

You'll have to debug to determine which. It would seem that the error is because you're starting your iteration at 1 instead of 0, I would think it should be:

For i = 0 To noOfAddedDvds - 1

So when you get to the index of noOfAddedDvds in your collection, that element will be an uninitialized struct with Nothing strings.

You'll definitely want to fix the iteration (indexes start at 0). Additionally, you may also benefit from initializing the String properties in your struct to String.Empty internally. Depends on whether you want similar errors to manifest as an exception or as an empty record. Sometimes the latter makes the problem more obvious since at runtime you'd see that your output started on the second record.

Sign up to request clarification or add additional context in comments.

3 Comments

This is an indexing issue - and I WOULD expect this error. His DVD array has been defined to have 100 elements in the first place remember...
The issue will be, when he comes to add element 3, dvd(3) will be null.
@MartinMilan: Ah, you're right. I missed the 100-element initialization. So it won't have an out of bounds error, it's just going to reach an uninitialized record.
0

Just a few pointers...

The Items collection on the ListBox is actually 0 indexed, by which I mean that instead of going "1,2,3", it actually goes (0,1,2).

That's what your problem is.

Hint - think about perhaps using a List instead of an array as well... (for dvd)

Comments

0

Your thing cries out for being rewritten in OO form:

Friend DVDGenres
   Undefined
   Comedy
   Action
   Adventure
   Sci-Fi
End Enum 

Friend Class DVD
    Public Property Title As String
    Public Property Director As String
    Public Property Genre As DVDGenres

    Public Sub New
        Title = ""
        Director = ""
        Genre = DVDGenres.Undefined
        ' other stuff too
    End Sub

    Public Overrides Function ToString As String
       Return Title
    End Sub


End Class

Now something to store them in. Arrays went out with Rubik's Cubes, so a List:

Private myDVDs As New List(of DVD)

A list and a class can do what arrays and structures can without the headaches. Add a DVD:

Dim d As New DVD
d.Name = TextBoxName.Text
d.Director = TextBoxDir.Text
d.Genre = comboboxGenre.SelectedItem

' add to the container:
myDVDs.Add(d)

Display all the DVDs in a ListBox to pick from:

AllDVDsLB.DataSource = myDVDs
AllDVDsLB.DisplayMember = "Title"

This will set your list as the datasource for the listbox. Whatever is in the List is automatically displayed without copying data into the Items collection. Then, say from selectedindex changed event, display the selected item details to some labels:

Label1.Text = Ctype(AllDVDsLB.SelectedItem, DVD).Title
Label2.Text = Ctype(AllDVDsLB.SelectedItem, DVD).Director
Label3.Text = Ctype(AllDVDsLB.SelectedItem, DVD).Genre.ToString

Iterate to do something like what is in the Question:

For Each d As DVD in myDVDs          ' CANT run out of data
    lstTitle.Items.Add(d.Title)
    lstDirector.Items.Add(d.Director)
    lstGenre.Items.Add(d.Genre.ToString) 
Next

Or iterate and reference with an Int32:

For n As Integer = 0 To myDVDs.Count - 1
    lstTitle.Items.Add(myDVDs(n).Title)
    ' etc
Next n

HTH

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.