Vb.net 班内代表
我有ListView和for循环来填充项目,创建的每个项目都有类TSMPPConnection的实例,这个类有属性ConnectionItem来保存ListView项目,我想从类内更改项目文本,请求来自对象事件,当我直接更改项目文本时,它会引发异常 其他信息:跨线程操作无效:控件 “lstConnections”是从其所在线程以外的线程访问的 创建于 代表: 我使用委托实现了这一点,但同样的错误Vb.net 班内代表,vb.net,delegates,Vb.net,Delegates,我有ListView和for循环来填充项目,创建的每个项目都有类TSMPPConnection的实例,这个类有属性ConnectionItem来保存ListView项目,我想从类内更改项目文本,请求来自对象事件,当我直接更改项目文本时,它会引发异常 其他信息:跨线程操作无效:控件 “lstConnections”是从其所在线程以外的线程访问的 创建于 代表: 我使用委托实现了这一点,但同样的错误 Delegate Sub dlg_WriteConnectionItemStatus(s As S
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
不需要调用方检查执行是否来自委托并避免无限循环
尝试1:使用具有相同结构的另一个子系统从原始子系统中的委托调用它
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
相同错误您必须调用控件或窗体,调用委托本身就等于直接调用它:
writeconnectionimstatus()
您可以通过为此创建扩展方法来简化:
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
但是,如果您的目标是.NET 3.5或更低版本,则必须坚持学员:
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
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