我有一个带有ListView的应用程序,我想循环遍历ListView中的每个项目。但我想在一个单独的线程中这样做。
这是一个非常简单的代码版本 - 但它的错误是相同的:
Private Sub StartToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartToolStripMenuItem.Click
pingThread = New Thread(AddressOf loopingRoutine)
pingThread.Start()
End Sub
Public Sub loopingRoutine()
For Each item As ListViewItem In ListView1.Items
MsgBox(item.Text)
Next
End Sub
导致以下错误:
跨线程操作无效:控制从其创建的线程以外的线程访问的“ListView1”。
为什么会这样?我在使用DataGridViews之前从未遇到过这个问题。
任何人都可以对此有所了解吗?
答案 0 :(得分:2)
您无法从后台线程访问WinForms项目。它们与UI线程相关联。如果您过去能够以不同的类型执行此操作,那么您不幸的是它有效。
每当您想要使用特定控件时,您需要Invoke
返回UI线程以访问其成员。在后台线程上执行诸如循环成员之类的操作是不可能的。
答案 1 :(得分:0)
有办法!希望我可以帮助其他人通过网络试图解决这个问题!
您需要使用委托线程调用项目并将其存储为列表。然后使用它...如果这是有道理的!
像这样:
Private Sub StartToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartToolStripMenuItem.Click
pingThread = New Thread(AddressOf loopingRoutine)
pingThread.Start()
End Sub
Public Sub loopingRoutine()
Dim myList = DirectCast(Invoke(New GetListViewDelegate(AddressOf GetListViewItems)), List(Of String))
For Each item As String In myList
Dim array() As String = item.Split(";")
MsgBox(array(0) & vbCrLf & array(1))
Next
End Sub
Private Delegate Function GetListViewDelegate() As List(Of String)
Public Function GetListViewItems() As List(Of String)
Return the list back to the delegate
Dim pathList = New List(Of String)
For Each item As ListViewItem In ListView1.Items
pathList.Add(item.Text & ";" & item.Index)
Next
Return pathList
End Function
这可能不是最好的方法 - 但对于一个快速而肮脏的程序,它应该足够了:)