Invoking ListView problem....
Hello,
This is my code:
vb.net Code:
Private Sub Button2_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Me.FolderBrowserDialog1.ShowDialog()
If Me.FolderBrowserDialog1.SelectedPath <> String.Empty Then
Me.TextBox2.Text = Me.FolderBrowserDialog1.SelectedPath
Dim deleg As New Thread(AddressOf UpdateFileList)
deleg.Start()
End If
Me.FolderBrowserDialog1.Reset()
End Sub
#End Region
Private Sub UpdateFileList()
Try
Dim _filenames As ReadOnlyCollection(Of String) = My.Computer.FileSystem. _
GetFiles(Me.TextBox2.Text, FileIO.SearchOption.SearchAllSubDirectories)
For Each filename As String In _filenames
Me.ImageList1.Images.AddStrip(ExtractAssociatedIcon(filename).ToBitmap)
If ListView1.InvokeRequired Then
Me.ListView1.Invoke(New UpdateProgressCallBack(AddressOf UpdateFileList))
Else
ListView1.Items. _
Add(filename, imageIndex:=Me.ImageList1.Images.Count - 1) _
.SubItems.Add(filename)
End If
Next
Catch ex as Exception
End Try
End Sub
If I wanted to add 3 icons, the LV would add them like it normally would, but then, for some reason, it enters the loop again and that's when it throws this error:
ex = {"Cross-thread operation not valid: Control 'ListView1' accessed from a thread other than the thread it was created on."}
I don't understand why, because I'm invoking the LV...
Thanks in advance!
Re: Invoking ListView problem....
You've structured the code incorrectly. If you're invoking the same method then the test for whether or not an invocation is required needs to be the FIRST thing you do, otherwise everything you've already done is going to be repeated when you do invoke. Your code should be like this:
vb.net Code:
Private Sub UpdateFileList()
Try
If ListView1.InvokeRequired Then
Me.ListView1.Invoke(New UpdateProgressCallBack(AddressOf UpdateFileList))
Else
Dim _filenames As ReadOnlyCollection(Of String) = My.Computer.FileSystem. _
GetFiles(Me.TextBox2.Text, FileIO.SearchOption.SearchAllSubDirectories)
For Each filename As String In _filenames
Me.ImageList1.Images.AddStrip(ExtractAssociatedIcon(filename).ToBitmap)
ListView1.Items. _
Add(filename, imageIndex:=Me.ImageList1.Images.Count - 1) _
.SubItems.Add(filename)
Next
End If
Catch ex As Exception
End Try
End Sub
If you want to do everything on the UI thread. I'm guessing that you don't want that so you need two methods, like this:
vb.net Code:
Private Sub UpdateFileList()
Try
Dim _filenames As ReadOnlyCollection(Of String) = My.Computer.FileSystem. _
GetFiles(Me.TextBox2.Text, FileIO.SearchOption.SearchAllSubDirectories)
For Each filename As String In _filenames
Me.ImageList1.Images.AddStrip(ExtractAssociatedIcon(filename).ToBitmap)
Me.UpdateListView(filename)
Next
Catch ex As Exception
End Try
End Sub
Private Delegate Sub UpdateListViewCallback(ByVal fileName As String)
Private Sub UpdateListView(ByVal fileName As String)
If ListView1.InvokeRequired Then
Me.ListView1.Invoke(New UpdateListViewCallback(AddressOf UpdateListView), fileName)
Else
ListView1.Items. _
Add(fileName, imageIndex:=Me.ImageList1.Images.Count - 1) _
.SubItems.Add(fileName)
End If
End Sub
or like this:
vb.net Code:
Private Sub UpdateFileList()
Try
Dim _filenames As ReadOnlyCollection(Of String) = My.Computer.FileSystem. _
GetFiles(Me.TextBox2.Text, FileIO.SearchOption.SearchAllSubDirectories)
Me.UpdateListView(_filenames)
Catch ex As Exception
End Try
End Sub
Private Delegate Sub UpdateListViewCallback(ByVal fileNames As ReadOnlyCollection(Of String))
Private Sub UpdateListView(ByVal fileNames As ReadOnlyCollection(Of String))
If ListView1.InvokeRequired Then
Me.ListView1.Invoke(New UpdateListViewCallback(AddressOf UpdateListView), fileNames)
Else
For Each filename As String In fileNames
Me.ImageList1.Images.AddStrip(ExtractAssociatedIcon(filename).ToBitmap)
Me.UpdateListView(filename)
ListView1.Items. _
Add(filename, imageIndex:=Me.ImageList1.Images.Count - 1) _
.SubItems.Add(filename)
Next
End If
End Sub
Re: Invoking ListView problem....
Thanks! That works perfectly! One more question though: the third code runs the first sub on the worker thread and the second one on the UI thread?
Re: Invoking ListView problem....
In both the second and third cases the UpdateListView method is called on the secondary thread and then it is invoked a second time via the delegate on the UI thread. The UpdateListView method essentially calls itself with the second call being made on the UI thread.