2016-01-31 2 views
0

У меня возникла проблема с чтением элемента из ListView. ListView находится в основном потоке, а часть, где я его прочитал, находится в другом классе и другом потоке. Мой код выглядит следующим образом:Чтение информации из ListView из другого потока в Visual Basic

Public Class Form1 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
     Dim ltm As ListViewItem = New ListViewItem 
     ltm.Text = "test1" 
     ltm.SubItems.Add("test2") 
     ltm.SubItems.Add("test3") 
     Me.ListView2.Items.Add(ltm) 
     Dim l As New test 
     Dim x As New Threading.Thread(AddressOf l.readout) 
    End Sub 
End Class 
Public Class test 
    Public Sub readout() 
     For Each i As ListViewItem In Form1.ListView2.Items 
      Dim command As String = i.SubItems(0).Text 
      Dim value As String = i.SubItems(1).Text 
      Dim executeon As String = i.SubItems(2).Text 
      MsgBox(command & vbCrLf & value & vbCrLf & executeon) 
     Next 
    End Sub 
End Class 

Я слышал о вызовах и нашел пример кода. Я также пробовал следующее:

Dim selectedItem = CStr((New Func(Of String)(Function() Form1.ListView2.Items(0).Text)).Invoke) 
     MsgBox(selectedItem) 

Однако это не сработало. Нет сообщений об ошибках, он просто не показывает никаких сообщений. Когда я удаляю threading и тот же класс, он работает просто отлично. Кто-нибудь знает, почему это не работает?

+0

Ошибка стандартного VB.NET с использованием Form1 в рабочем потоке создает * новый * экземпляр класса Form1. Вы не можете увидеть его, если не добавить Form1.ShowDialog(). Если вы исправите эту ошибку, вы получите InvalidOperationException. Не связывайтесь с пользовательским интерфейсом в рабочем потоке, дайте ему список (Of String) для работы. –

ответ

0

В принципе, вы не можете коснуться нити пользовательского интерфейса из другого потока. Трудно точно сказать, что вы пытаетесь сделать, но вы, безусловно, можете проверить, используете ли вы поток, отличный от UI, и продолжаете выполнение в потоке пользовательского интерфейса с помощью InvokeRequired и BeginInvoke.

Public Class Form1 

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
     Dim ltm As ListViewItem = New ListViewItem 
     ltm.Text = "test1" 
     ltm.SubItems.Add("test2") 
     ltm.SubItems.Add("test3") 
     Me.ListView2.Items.Add(ltm) 
     Dim l As New test(ListView2) 
     Dim x As New Threading.Thread(AddressOf l.readout) 
     x.Start() 
    End Sub 
End Class 

Public Class test 

    Public Sub New(listview As ListView) 
     _listview = listview 
    End Sub 

    Private _listview As ListView 

    Public Sub readout() 
     If _listview.InvokeRequired Then 
      _listview.BeginInvoke(New Action(AddressOf readout)) 
     Else 
      For Each i As ListViewItem In Form1.ListView2.Items 
       Dim command As String = i.SubItems(0).Text 
       Dim value As String = i.SubItems(1).Text 
       Dim executeon As String = i.SubItems(2).Text 
       MsgBox(command & vbCrLf & value & vbCrLf & executeon) 
      Next 
     End If 
    End Sub 
End Class 
+0

Это очень помогло мне. Спасибо за ваш ответ, ты спас меня! –

+0

Теперь я столкнулся с другой проблемой. Представленный код был тестовым проектом, так как фактический уровень слишком велик для отображения. В тестовом проекте он работает отлично, но в фактическом он дает мне ошибку с ошибкой. Есть ли какие-нибудь подсказки, что это может быть? –

Смежные вопросы