从其他类更新GUI中的列表框

时间:2015-01-24 13:02:55

标签: vb.net listbox

我在主vb.net表单上有一个列表框,我用它来显示正在运行的服务器程序的状态消息。我的实际程序由许多不同的类(在单独的文件中)组成,我希望能够从每个类调用Sub frm.UpdateList(" With Info in Here")写入列表框。

如果我从frm类调用frm.UpdateList或UpdateList,它会很好地写入列表框,但是如果我从任何其他类调用它没有任何反应(我也不会收到错误)。

我尝试过和不共享(并将frm改为我),但都没有按照我的意愿行事。

是否有人能够帮助我理解为什么这不起作用,我已经调用了该项,它确实被添加到但不是来自一个单独的类(这是我需要它做的)。

非常感谢!

Private Delegate Sub UpdateListDelegate(ByVal itemName As String)
    Public Shared Sub UpdateList(ByVal itemName As String)
        If frm.InvokeRequired Then
            frm.Invoke(New UpdateListDelegate(AddressOf UpdateList), itemName)
        Else
                            frm.ListBox1.Items.Insert(0, DateTime.Now.ToString & ": " & itemName)
        End If
End Sub

编辑:尝试2,以下感谢Idle_Mind在frm类上工作(frm是主窗体和唯一的窗体)但是当从其他类调用时它仍然不会写入列表框(并且不会发生错误):

Public Shared Sub UpdateList(ByVal itemName As String)
    Dim frm As Form = My.Application.ApplicationContext.MainForm
    If Not IsNothing(frm) Then
        Dim matches() As Control = frm.Controls.Find("ListBox1", True)
        If matches.Length > 0 AndAlso TypeOf matches(0) Is ListBox Then
            Dim LB As ListBox = DirectCast(matches(0), ListBox)
            LB.Invoke(New MethodInvoker(Sub() LB.Items.Insert(0, DateTime.Now.ToString & ": " & itemName)))
        End If
    End If
End Sub

1 个答案:

答案 0 :(得分:1)

  

我的主vb.net表单上有一个列表框

这只适用于启动表单,并不是一个好的设计。考虑其他方法:

Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim soc As New SomeOtherClass
        soc.Foo()
    End Sub

End Class

Public Class SomeOtherClass

    Public Sub Foo()
        Dim msg As String = "Hello?!"
        Helper.UpdateList(msg) ' <-- You can do this from any class...
    End Sub

End Class

Public Class Helper

    Public Shared Sub UpdateList(ByVal itemName As String)
        Dim frm As Form = My.Application.ApplicationContext.MainForm
        If Not IsNothing(frm) Then
            Dim matches() As Control = frm.Controls.Find("ListBox1", True)
            If matches.Length > 0 AndAlso TypeOf matches(0) Is ListBox Then
                Dim LB As ListBox = DirectCast(matches(0), ListBox)
                LB.Invoke(New MethodInvoker(Sub() LB.Items.Insert(0, DateTime.Now.ToString & ": " & itemName)))
            End If
        End If
    End Sub

End Class

enter image description here

其他需要更多工作的正确方法可能包括:

(1)在创建主要表单时将其引用传递给其他类。然后这些类可以直接向上移动ListBox,也可以按照Plutonix的建议调用其中的方法。以下是此操作的示例:

Public Class Form1

    Public Sub UpdateList(ByVal itemName As String)
        ListBox1.Invoke(New MethodInvoker(Sub() ListBox1.Items.Insert(0, DateTime.Now.ToString & ": " & itemName)))
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim soc As New SomeOtherClass(Me)
        soc.Foo()
    End Sub

End Class

Public Class SomeOtherClass

    Private _Main As Form1

    Private Sub New()
    End Sub

    Public Sub New(ByVal MainForm As Form1)
        _Main = MainForm
    End Sub

    Public Sub Foo()
        If Not IsNothing(_Main) Then
            _Main.UpdateList("Hello?!")
        End If
    End Sub

End Class

您必须以类似的方式修改所有其他类,以便他们可以接收您的表单实例。

(2)使其他类引发主窗体在创建这些类时订阅的自定义事件。