bjwade62 Posted February 1, 2006 Posted February 1, 2006 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? 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 ListviewProblem.bmp Quote
Cags Posted February 1, 2006 Posted February 1, 2006 Try doing this 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 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. Quote Anybody looking for a graduate programmer (Midlands, England)?
Leaders snarfblam Posted February 2, 2006 Leaders Posted February 2, 2006 (edited) 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. Edited February 2, 2006 by snarfblam Quote [sIGPIC]e[/sIGPIC]
bjwade62 Posted February 2, 2006 Author Posted February 2, 2006 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! Quote
Cags Posted February 2, 2006 Posted February 2, 2006 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. 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). Quote Anybody looking for a graduate programmer (Midlands, England)?
bjwade62 Posted February 2, 2006 Author Posted February 2, 2006 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. 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. 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). Quote
Cags Posted February 2, 2006 Posted February 2, 2006 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. 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. Quote Anybody looking for a graduate programmer (Midlands, England)?
Leaders snarfblam Posted February 2, 2006 Leaders Posted February 2, 2006 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. 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 Quote [sIGPIC]e[/sIGPIC]
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.