2016-12-08 5 views
-1

Ich habe Listview mit for-Schleife Elemente zu füllen, erstellt jedes Element gibt es eine Instanz der Klasse TSMPPConnection und diese Klasse hat Eigenschaft ConnectionItem Listview-Element zu halten, mag ich von Artikel Text ändern Innerhalb der Klasse kommt diese Anfrage von einem Objektereignis, wenn ich den Itemtext direkt ändere, wird eine Ausnahme ausgelöst.Delegierten innerhalb der Klasse

Zusätzliche Informationen: Cross-Thread-Betrieb nicht gültig: Steuer 'lstConnections' von einem anderen Thread als dem Thread zugegriffen es auf erstellt wurde.

Delegierten: ich Delegierten verwendet, um dies aber denselben Fehler zu erreichen.

Delegate Sub dlg_WriteConnectionItemStatus(s As String) 
    Sub WriteConnectionItemStatus(s As String) 

     Dim dlg As New dlg_WriteConnectionItemStatus(AddressOf WriteConnectionItemStatus) 
     dlg.Invoke(s) 

     'there is no InvokeRequired to check if execution come from delgate and avoid infinite loop 
     If ConnectionItem IsNot Nothing Then ConnectionItem.SubItems(6).Text = s 

    End Sub 

Es gibt keine InvokeRequired zu überprüfen, ob die Ausführung von Delegierten kommen und vermeiden Endlosschleife

1 Versuchen: eine andere Unter mit derselben Struktur verwenden es in Originalunter von Delegierten zu nennen.

Delegate Sub dlg_WriteConnectionItemStatus(s As String) 
    Sub WriteConnectionItemStatus(s As String) 

     Dim dlg As New dlg_WriteConnectionItemStatus(AddressOf WriteConnectionItemStatus_Interface) 
     dlg.Invoke(s) 

    End Sub 

    Sub WriteConnectionItemStatus_Interface(s As String) 

     If ConnectionItem IsNot Nothing Then ConnectionItem.SubItems(6).Text = s 

    End Sub 

gleichen Fehler

Antwort

1

Sie müssen eine Kontrolle oder ein Formular aufrufen, das Aufrufen der Delegierten selbst gleich ist, nur es direkt anrufen: WriteConnectionItemStatus().

können Sie die Dinge vereinfachen, indem eine Erweiterungsmethode für diese Stelle zu schaffen:

Imports System.Runtime.CompilerServices 

Public Module Extensions 
    <Extension()> _ 
    Public Sub InvokeIfRequired(ByVal Control As Control, ByVal Method As Action) 
     If Control.InvokeRequired = True Then 
      Control.Invoke(Method) 
     Else 
      Method.Invoke() 
     End If 
    End Sub 
End Module 

es nutzen zu können, die übergeordnete Listview des Elements erhalten müssen. Wenn Sie Targeting .NET 4.0 oder höher können Sie Lambda-Ausdrücke anstelle der normalen Delegierten verwenden, die einfacher zu schreiben und viel flexibler:

Sub WriteConnectionItemStatus(s As String) 

    If ConnectionItem IsNot Nothing Then _ 
     ConnectionItem.ListView.InvokeIfRequired(Sub() ConnectionItem.SubItems(6).Text = s) 
End Sub 

Allerdings, wenn Sie Targeting .NET 3.5 oder niedriger müssen Sie an die Delegierten haften:

Delegate Sub SetSubItemTextDelegate(Item As ListViewItem, Index As Integer, Text As String) 

Sub WriteConnectionItemStatus(s As String) 

    If ConnectionItem IsNot Nothing Then _ 
     ConnectionItem.ListView.InvokeIfRequired(New SetSubItemTextDelegate(AddressOf SetSubItemText), ConnectionItem, 6, s) 
End Sub 

Sub SetSubItemText(Item As ListViewItem, Index As Integer, Text As String) 'Generalized method for flexibility. 
    Item.SubItems(Index).Text = Text 
End Sub 
+0

vielen Dank mein Problem gelöst :); – Realbitt