How to use a listview control

I am trying to convert a project from VB6 to VB2017 but have very little experience with .net.

I am attempting to use a ListView control to display hardware drives information. I can get the data OK, but the control is baffling. I need four columns, and it seems that you need to add ColumnHeaders to create the columns. To append the data I create four ListView items, each with a sub item which I populate. However the items are not  displayed in columns correctly.

Here is the code
    Sub DrivesList()
        'Dim objDrv As DriveInfo
        Dim strDrives() As String
        Dim strVolumes() As String
        Dim strTypes() As String
        Dim strSizes() As String

        Dim allDrives() As DriveInfo = DriveInfo.GetDrives()
        Dim i As Integer
        Dim j As Integer

        With Me.lvDrives
            .View = View.Details
            Dim ColumnHeader1 As New ColumnHeader
            With ColumnHeader1
                .Text = "Drive"
                .TextAlign = HorizontalAlignment.Left
                .Width = 146
            End With
            .Columns.Add(ColumnHeader1)

            Dim ColumnHeader2 As New ColumnHeader
            With ColumnHeader2
                .Text = "Volume"
                .TextAlign = HorizontalAlignment.Left
                .Width = 146
            End With
            .Columns.Add(ColumnHeader2)

            Dim ColumnHeader3 As New ColumnHeader
            With ColumnHeader3
                .Text = "Type"
                .TextAlign = HorizontalAlignment.Left
                .Width = 146
            End With
            .Columns.Add(ColumnHeader3)

            Dim ColumnHeader4 As New ColumnHeader
            With ColumnHeader4
                .Text = "Size"
                .TextAlign = HorizontalAlignment.Right
                .Width = 146
            End With
            .Columns.Add(ColumnHeader4)
            For Each objDrv In allDrives
                ReDim Preserve strDrives(i)
                ReDim Preserve strVolumes(i)
                ReDim Preserve strTypes(i)
                ReDim Preserve strSizes(i)
                With objDrv
                    If .IsReady Then
                        strDrives(i) = .RootDirectory.Name
                        strSizes(i) = .TotalSize
                        strVolumes(i) = .VolumeLabel

                    End If

                    strTypes(i) = .DriveType
                    Select Case .DriveType
                        Case 0 : strTypes(i) = "Unknown"
                        Case 1 : strTypes(i) = "Removable Drive"
                        Case 2 : strTypes(i) = "Hard Disk Drive"
                        Case 3 : strTypes(i) = "Network Drive"
                        Case 4 : strTypes(i) = "CDROM Drive"
                        Case 5 : strTypes(i) = "RAM Disk Drive"
                    End Select

                End With
                i = i + 1

            Next objDrv
            For j = 0 To i - 1
                Dim li1 As New ListViewItem(i - 1)
                li1.SubItems.Add(strDrives(j))
                .Items.Add(li1)
            Next j
            For j = 0 To i - 1
                Dim li2 As New ListViewItem(i - 1)
                li2.SubItems.Add(strVolumes(j))
                .Items.Add(li2)
            Next j
            For j = 0 To i - 1
                Dim li3 As New ListViewItem(i - 1)
                li3.SubItems.Add(strTypes(j))
                .Items.Add(li3)
            Next j
            For j = 0 To i - 1
                Dim li4 As New ListViewItem(i - 1)
                li4.SubItems.Add(strSizes(j))
                .Items.Add(li4)
            Next j
        End With

    End Sub

Open in new window

LVL 77
GrahamSkanRetiredAsked:
Who is Participating?
 
Chris WatsonSoftware DeveloperCommented:
Or this:

Sub DrivesList()
    
    lvDrives.View = View.Details

    Dim driveColumnHeader = New ColumnHeader()
    With driveColumnHeader
        .Text      = "Drive"
        .TextAlign = HorizontalAlignment.Left
        .Width     = 146
    End With
    lvDrives.Columns.Add(driveColumnHeader)

    Dim volumeColumnHeader = New ColumnHeader()
    With volumeColumnHeader
        .Text      = "Volume"
        .TextAlign = HorizontalAlignment.Left
        .Width     = 146
    End With
    lvDrives.Columns.Add(volumeColumnHeader)

    Dim typeColumnHeader = New ColumnHeader()
    With typeColumnHeader
        .Text      = "Type"
        .TextAlign = HorizontalAlignment.Left
        .Width     = 146
    End With
    lvDrives.Columns.Add(typeColumnHeader)

    Dim sizeColumnHeader = New ColumnHeader()
    With sizeColumnHeader
        .Text      = "Size"
        .TextAlign = HorizontalAlignment.Right
        .Width     = 146
    End With
    lvDrives.Columns.Add(sizeColumnHeader)


    Dim driveDisplayInfos = DriveInfo.GetDrives.Select(
        Function(driveInfo)

            Return New With
            {
                .Drive  = driveInfo.RootDirectory.Name,
                .Volume = If(driveInfo.IsReady, 
                             driveInfo.VolumeLabel.ToString(), 
                             String.Empty),
                .Type   = GetDriveTypeDescription(driveInfo.DriveType),
                .Size   = If(driveInfo.IsReady, 
                             driveInfo.TotalSize.ToString(),
                             String.Empty)
            }

        End Function)


    For Each driveDisplayInfo In driveDisplayInfos
        
        Dim listViewItem = New ListViewItem()
        listViewItem.Text = driveDisplayInfo.Drive
        listViewItem.SubItems.Add(driveDisplayInfo.Volume)
        listViewItem.SubItems.Add(driveDisplayInfo.Type)
        listViewItem.SubItems.Add(driveDisplayInfo.Size)

        lvDrives.Items.Add(listViewItem)

    Next

End Sub

Private Shared Function GetDriveTypeDescription(
    ByVal driveType As DriveType) As String

    Select Case driveType
        Case DriveType.Unknown
            Return "Unknown"
        Case DriveType.Removable
            Return "Removable Drive"
        Case DriveType.Fixed 
            Return "Hard Disk Drive"
        Case DriveType.Network
            Return "Network Drive"
        Case DriveType.CDRom 
            Return "CDROM Drive"
        Case DriveType.Ram
            Return "RAM Disk Drive"
        Case Else
            Return "Unknown"
    End Select

End Function

Open in new window

0
 
Chris WatsonSoftware DeveloperCommented:
Replace lines 71-91 with:

For j = 0 To i - 1
    With .Items.Add(strDrives(j))
        .SubItems.Add(strVolumes(j))
        .SubItems.Add(strTypes(j))
        .SubItems.Add(strSizes(j))
    End With
Next j

Open in new window


Also, the enum values in your drive type are wrong. Replace lines 59-66 with:

Select Case .DriveType
	Case DriveType.Unknown : strTypes(i) = "Unknown"
	Case DriveType.Removable : strTypes(i) = "Removable Drive"
	Case DriveType.Fixed : strTypes(i) = "Hard Disk Drive"
	Case DriveType.Network : strTypes(i) = "Network Drive"
	Case DriveType.CDRom : strTypes(i) = "CDROM Drive"
	Case DriveType.Ram : strTypes(i) = "RAM Disk Drive"
End Select

Open in new window

0
 
GrahamSkanRetiredAuthor Commented:
Thanks Chris. I am trying the first modifications that you suggest, but I get an inexplicable (to me) NullReferenceException 'Object reference not set to an instance of the object' on line 53  - inexplicable because the previous line works OK with the same object.
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
GrahamSkanRetiredAuthor Commented:
It seems to work in the immediate window.

?objdrv.totalsize
239582904320

I thought that I was expecting the same implied conversion, so I also tried:
strSizes(i) = ToString(.TotalSize)

Open in new window

but it raises the same error.
0
 
GrahamSkanRetiredAuthor Commented:
You second suggestion looks good, so I will try that now
0
 
GrahamSkanRetiredAuthor Commented:
That works perfectly so, unless  you feel particularly challenged, I will not pursue the exception problem.
0
 
Chris WatsonSoftware DeveloperCommented:
Is it line 53 or 52?

It could be that objDrive.RootDirectory is null. If so, you'd get a NullReferenceException when you try to access the Path property.
0
 
GrahamSkanRetiredAuthor Commented:
Hmm interesting.
Stepping through, the message appears when line 52   "strDrives(i) = .RootDirectory.Name" is executed
                    If .IsReady Then
                        strDrives(i) = .RootDirectory.Name
                        strSizes(i) = ToString(.TotalSize)
                        strVolumes(i) = .VolumeLabel

Open in new window


However the error symbol appears at the end of the next line "strSizes(i) = ToString(.TotalSize)"
In VB6 the error line itself gets highlighted. I am not familiar enough with .Net to be certain of where the error actually occurs.

Typing into the immediate window it looks like:
?objdrv.RootDirectory.Name
"C:\"

Thank you. In case you think of something else I'll give it another 12 hours before accepting your second comment as the answer.
0
 
GrahamSkanRetiredAuthor Commented:
The procedure did what I was trying to do, plus it showed some general techniques that should be useful as I get further into the project.

Thank you
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.