Link to home
Start Free TrialLog in
Avatar of randys106
randys106Flag for United States of America

asked on

List of (myClass) troubles

I have a class called Patients with three properties; Patient.Name as string, Patient.ID as integer, Patient.ExternalID as string.  

The following code works fine.  That is, the listbox loads.
   Private Sub frmPatientLookup_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Me.PatientsTableAdapter.Fill(Me.PatientsDataSet.Patients)
        For Each r In PatientsDataSet.Tables(2).Rows
            lstPatients.Items.Add(r(2) & ", " & r(1))
        Next
    End Sub

Open in new window

r(2) is the Last Name, r(1) is the First Name.

But, I am trying to populate a list consisting of the Patents Class.  

This code does not work:
 Private PatientList As List(Of Patients)
 Private Sub frmPatientLookup_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        PatientList = New List(Of Patients)
        Dim aPatient As Patients
        Me.PatientsTableAdapter.Fill(Me.PatientsDataSet.Patients)
        For Each r In PatientsDataSet.Tables(2).Rows
            lstPatients.Items.Add(r(2) & ", " & r(1))
            aPatient.Name = r(2) & ", " & r(1)
            aPatient.ID = r(0)
            aPatient.ExternalID = r(3)
            PatientList.Add(aPatient)
        Next
    End Sub

Open in new window

There are (at least) three problems:
1) I get an warning telling me that "Variable 'aPatient' is used before it has been assigned a value. A null reference exception could result at runtime."
 2) It does not load the list
3) It only loads the first item in the dataset into the listbox.

What am I doing wrong?
ASKER CERTIFIED SOLUTION
Avatar of Qlemo
Qlemo
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
It does not load the list
It does not load the list because as the first warning/error tells you there is a null reference exception occurring on line 8. This is corrected by what the others have mentioned. Make sure you are not using On Error in your code. That old VB6-style of error handling should be abandoned in favor of Try/Catch. Try/Catch is easier to follow/understand and debug.
Avatar of randys106

ASKER

Let's see...
Kaufmed nailed it.  I am an old VB6 guy who is trying to make the transition to .net.  Trying, and mostly failing.  I an not using OnError.  I do not use Try/catch here.  But it would be nice to get an error so I could know something was wrong.
 
Tried what GHz suggested but it did not change anything.  

I'm not sure exactly what I should do based on what Olemo said.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I think most has been answered, but I will try to add something:

I think in VB6, Doing 'Dim thing As MyClass' would create a reference to 'the' MyClass instance.

In .NET, you are only defining a variable to do this. You always have to create a new instance of a class if you want to use it. So in your first post you are only defining the variable but not initializing it to an actual instance.

You can do either:

Dim instance As MyClass = New MyClass()

Or:

Dim instance As New MyClass()

Note: you can omit the () in VB.NET when you are using the default constructor
Note: my personal preference is the form "Dim instance As MyClass = New MyClass()" as it is more explicit (also it looks more like C# which is my preferred language :))

Hope this helps!
*No Points*

Proof of concept project based on other experts input (Note: My table columns are not the same as yours so the column identifiers are off, same with my table identifier in the dataset):
Public Class Form1
	Private PatientList As List(Of Patient)
	Private Sub OnLoad(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
		PatientList = New List(Of Patient)
		PatientsTableAdapter.Fill(PatientsDataSet.Patients)
		Dim aPatient As Patient
		For Each row In PatientsDataSet.Tables(0).Rows
			ListBox1.Items.Add(String.Format("{0}, {1}", row(3), row(2)))
			aPatient = New Patient() With {.ID = row(0), .ExternalID = row(1), .Name = String.Format("{0}, {1}", row(3), row(2))}
			If Not aPatient Is Nothing Then
				PatientList.Add(aPatient)
			End If
		Next
	End Sub
End Class

Public Class Patient
	Public Property ID() As Integer
	Public Property ExternalID() As String
	Public Property Name() As String
End Class

Open in new window

Produces the following output -User generated imageAnd shows the following in the PatientList -User generated imageUser generated imageUser generated image-saige-
And if you really want to get fancy, why create a new listbox item for each patient, when you can just use the patient list as the datasource for your listbox control:
Public Class Form1
	Private PatientList As List(Of Patient)
	Private Source As New BindingSource

	Private Sub OnLoad(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
		PatientList = New List(Of Patient)
		PatientsTableAdapter.Fill(PatientsDataSet.Patients)
		Dim aPatient As Patient
		For Each row In PatientsDataSet.Tables(0).Rows
			aPatient = New Patient() With {.ID = row(0), .ExternalID = row(1), .Name = String.Format("{0}, {1}", row(3), row(2))}
			If Not aPatient Is Nothing Then PatientList.Add(aPatient)
		Next
		Source.DataSource = PatientList
		ListBox1.DataSource = Source
	End Sub
End Class

Public Class Patient
	Public Property ID() As Integer
	Public Property ExternalID() As String
	Public Property Name() As String

	Public Overrides Function ToString() As String
		Return Name
	End Function
End Class

Open in new window

Produces the same output as above -User generated imageAnd since I overrided the ToString method of the Patient class, now the PatientList shows -User generated image-saige-
Try this :
    Private PatientList As List(Of Patients) = Nothing
    Private Sub frmPatientLookup_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        PatientList = New List(Of Patients)
        Me.PatientsTableAdapter.Fill(Me.PatientsDataSet.Patients)
        For Each r In PatientsDataSet.Tables(2).Rows
            lstPatients.Items.Add(r(2) & ", " & r(1))
            PatientList.Add(New Patients With {.Name = r(2).ToString & ", " & r(1).ToString, _
                                               .ID = r(0).ToString, .ExternalID = r(3).ToString})
        Next
    End Sub

Open in new window