2015-01-24 3 views
2

У меня есть список в моей основной форме vb.net, которую я использую для отображения сообщений о статусе из программы сервера, которую я запускаю. Моя фактическая программа состоит из множества разных классов (в отдельных файлах), и я хотел бы, чтобы это было возможно - вызвать Sub frm.UpdateList («With Info in Here») из каждого класса для записи в список.update listbox в GUI из других классов

Если я вызываю frm.UpdateList или UpdateList из класса frm, он отлично записывает в список, но если я его вызываю из любого другого класса, ничего не происходит (я тоже не получаю ошибку).

Я пробовал с и без совместного использования (и менял 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 

Edit: Попробуйте 2, со следующими благодаря Idle_Mind работает на классе FRM (FRM является основной формой и только форма), но она до сих пор не пишут в ListBox при вызове из других классов (и нет возникают ошибки):

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 
+0

Является ли frm объектом формы или именем класса (формы)? –

+0

Почему бы просто не предоставить публичный метод в форме, которую может вызвать любой актер? – Plutonix

ответ

1

у меня есть ListBox на моей основной форме 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) Сделайте другие классы поднимет пользовательское событие, которое подписывается основной формой при создании этих классов.

+0

Спасибо за ответы, я должен был сказать, что я использовал выше, но доволен другими подходами. Поскольку я новичок в этом, я выбрал то, что, как я думал, будет работать (но может и не быть правильным). Спасибо за советы! – user1829564

+0

Я уверен, что это просто то, что я делаю неправильно, но с приведенным выше примером, если я помещаю его в общий или дополнительный суб и вызываю его из других классов, он не обновляет список. Должен ли я создавать sub в каждом классе, как в приведенном выше примере? – user1829564

+0

Является ли данная форма «Объектом запуска» в Project -> Properties? –

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