Listview Problem adding SOME subitems??

bjwade62

Centurion
Joined
Oct 31, 2003
Messages
104
Here's my code that adds items (filenames) and subitems (file dates and size) to a listview control. The problem is that some of the subitems (file dates) don't get added (see attached image). I've removed my try, end try statements and no error. I step through the code and still no error. I'm totally Stuck. Can anyone help me?

Visual Basic:
            Dim BrowseFolder As New FolderBrowserDialog
            BrowseFolder.ShowNewFolderButton = False
            BrowseFolder.Description = "Select folder for LEFT list."
            BrowseFolder.ShowDialog()
            cmboLeft.Items.Add(BrowseFolder.SelectedPath)
            cmboLeft.Text = BrowseFolder.SelectedPath
            cmboLeft.Refresh()
            lvwLeftList.Items.Clear()
            Dim file As String, files As String()
            Dim Fdate As String = ""
            files = System.IO.Directory.GetFiles(BrowseFolder.SelectedPath)
            Dim ex As Integer = 0
            For Each file In files

                Dim SlashLen As Integer = file.LastIndexOf("\") + 1
                Dim FileLen As Integer
                FileLen = Len(file)

                Dim RemainLen As Integer
                RemainLen = FileLen - SlashLen

                Dim StrFileOnly As String
                StrFileOnly = file.Substring(SlashLen, RemainLen)

                Dim information As System.IO.FileInfo
                information = My.Computer.FileSystem.GetFileInfo(file)
                Dim fileDate As String
                fileDate = information.LastWriteTime

                Dim fileSize As Long
                fileSize = My.Computer.FileSystem.GetFileInfo(file).Length
                If fileSize < 1024 Then
                    fileSize = 1
                Else
                    fileSize = fileSize / 1024
                End If

                lvwLeftList.Items.Add(StrFileOnly, 0) ' (cmboLeft.Items.Count - 1))
                lvwLeftList.Items(ex).SubItems.Add(fileDate)
                lvwLeftList.Items(ex).SubItems.Add(fileSize & " KB")

                ex = ex + 1
                StatusStrip1.Refresh()
                lvwLeftList.Refresh()
                ToolStripStatusLeftShown.Text = "Files: " & lvwLeftList.Items.Count
            Next
 

Attachments

Try doing this
Visual Basic:
Dim tmpItem As ListViewItem
tmpItem = New ListViewItem(StrFileOnly, 0)
tmpItem.SubItems.Add(fileDate)
tmpItem.SubItems.Add(fileSize & " KB")
lvwLeftList.Items.Add(tmpItem)
instead of this
Visual Basic:
lvwLeftList.Items.Add(StrFileOnly, 0) ' (cmboLeft.Items.Count - 1) ) 
lvwLeftList.Items(ex).SubItems.Add(fileDate)
lvwLeftList.Items(ex).SubItems.Add(fileSize & " KB")
ex = ex + 1
Also on a side note I believe if you call lvwLeftList.BeginUpdate() before the loop and lvwLeftList.EndUpdate() afterwards it will speed it up. I would also recommend against calling refresh during the loop.

EDIT:- Might not help with your problem, its very hard to test that without having your application, but it may help.
 
If your ListView is sorted, the items may not be displayed in order, or it may be that they are not added in order. Your code (specifically the use of the 'ex' variable) assumes that as items are added they will have consecutive indecies, which may not be the case.

BeginUpdate and EndUpdate will speed things up, and no you shouldn't call refresh. Also, in version 1.1 (I haven't tested other versions) while using visual styles, if you modify the contents of the ListView without first calling BeginUpdate exceptions are thrown and caught within System.Windows.Forms.dll. No exceptions will make their way into your code and it won't crash your app, but it can make debugging difficult and cause terrible lag while updating the ListView.
 
Last edited:
Thanks Cags and Marble eater. I have it working now, but I still have a question about refreshing inside a loop. The reason I did it is so the user can see the list view filling up. When I leave it out the program looks like it's not responding. I know I could add a form that says please wait... but is there a better way?

Thanks Again!
 
If you take out the refresh and also use the Begin and End Update methods, it shouldn't take more than a second or two to fill up unless your dealing with an awefull lot of items. The following lines are probably causing an awefull lot of slowdown.
Visual Basic:
StatusStrip1.Refresh()
lvwLeftList.Refresh()
ToolStripStatusLeftShown.Text = "Files: " & lvwLeftList.Items.Count
When I was working on my placement I was loading 5000 or more items into a listview and that didn't take long even on a reasonably old pc once i'd optimised it. The first time I tried however it was taking over a minute because of the control doing things like refresh and changing label values (even doing calling console.writeline slowed it down a fair bit).
 
Yeah I took those items out last night after your first message. I have about 1000 items that take about 8 seconds to fill now. Which is way down from before I incorperated your suggestions. Thanks again Cags. You've be a constant help to me and I honestly appreciate it.

Cags said:
If you take out the refresh and also use the Begin and End Update methods, it shouldn't take more than a second or two to fill up unless your dealing with an awefull lot of items. The following lines are probably causing an awefull lot of slowdown.
Visual Basic:
StatusStrip1.Refresh()
lvwLeftList.Refresh()
ToolStripStatusLeftShown.Text = "Files: " & lvwLeftList.Items.Count
When I was working on my placement I was loading 5000 or more items into a listview and that didn't take long even on a reasonably old pc once i'd optimised it. The first time I tried however it was taking over a minute because of the control doing things like refresh and changing label values (even doing calling console.writeline slowed it down a fair bit).
 
It might also make a big difference if you make an array of ListViewItems then use the AddRange() method after the loop rather than adding to teh ListView in the loop. Heres a quick example.
Visual Basic:
        ListView1.BeginUpdate()
        Dim i As Single = 0
        Dim myArray(999) As ListViewItem
        For i = 0 To 999
            Dim tmpItem As New ListViewItem("Item " & i.ToString())
            tmpItem.SubItems.Add("col two")
            tmpItem.SubItems.Add("col three")
            myArray(i) = tmpItem
        Next
        ListView1.Items.AddRange(myArray)
        ListView1.EndUpdate(
Hope that makes sense, I'm in a rush because I'm on my way out. If you have any questions just ask and myself or someone else will reply.
 
8000 items can't be displayed at once in the ListView. The user will see the ListView fill up and then all he would see is the scrollbar shrinking, and even that would only go until a certain point.

Perhaps the best option to display the progress to a user would be to use a progress bar. Just slap it on your form, and every 10 or 100 or whatever iterations in your loop, update the progress bar.
Visual Basic:
Dim FileCount As Integer = 999
Const UpdateFrequency As Integer = 10
'Realistically, once every hundred items should suffice.
 
ProgressBar1.Minimum = 0
ProgressBar1.Maximum = (FileCount + 1) \\ UpdateFrequency
ProgressBar1.Value = 0
 
For int i = 0 to FileCount
    'Do things, and stuff. Like putting things in list-a-ma-bobs.
 
    'And then do this.
    If i Mod UpdateFrequency = 0 Then
        ProgressBar1.Value += 1
        Application.DoEvents()
    End If
Next
 
Back
Top