vb.net: listbox.items.add() throws exception in same class

寵の児 提交于 2019-12-25 18:12:58

问题


I'm not even sure I understand this situation enough to come up with a proper title. I come from a modest understanding of VB6 and having to climb a steep learning curve for VB 2010.

I am trying to create a multi-client server program that will communicate with my Enterprise iPhone app. I found a relatively simple example to build upon here: http://www.strokenine.com/blog/?p=218. I have been able to modify the code enough to make it work with my app, but with one glitch: I can't get access to the controls on the form to add items, even though the method is invoked within the form's class. (I tried this on the original code too, and it does the same thing. I don't know how the author managed to get it to work.)

Here's the code segment in question:

Public Class Server 'The form with the controls is on/in this class.
Dim clients As New Hashtable 'new database (hashtable) to hold the clients


    Sub recieved(ByVal msg As String, ByVal client As ConnectedClient)
    Dim message() As String = msg.Split("|") 'make an array with elements of the message recieved
    Select Case message(0) 'process by the first element in the array
        Case "CHAT" 'if it's CHAT
            TextBox3.Text &= client.name & " says: " & " " & message(1) & vbNewLine 'add the message to the chatbox
            sendallbutone(message(1), client.name) 'this will update all clients with the new message
            '                                       and it will not send the message to the client it recieved it from :)
        Case "LOGIN" 'A client has connected
            clients.Add(client, client.name) 'add the client to our database (a hashtable)
            ListBox1.Items.Add(client.name) 'add the client to the listbox to display the new user
    End Select

End Sub

Under Case "LOGIN" the code tries to add the login ID to the listbox. It throws an exception: "A first chance exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll" The listbox (all controls, for that matter) is in the same class, Server.vb and Server.vb [Design].

The data comes in from another class that is created whenever a client logs on, which raises the event that switches back to the Server class:

Public Class ConnectedClient

Public Event gotmessage(ByVal message As String, ByVal client As ConnectedClient)    'this is raised when we get a message from the client
Public Event disconnected(ByVal client As ConnectedClient)    'this is raised when we get the client disconnects

Sub read(ByVal ar As IAsyncResult) 'this will process all messages being recieved
    Try
        Dim sr As New StreamReader(cli.GetStream) 'initialize a new streamreader which will read from the client's stream
        Dim msg As String = sr.ReadLine() 'create a new variable which will be used to hold the message being read
        RaiseEvent gotmessage(msg, Me) 'tell the server a message has been recieved. Me is passed as an argument which represents 
        '                               the current client which it has recieved the message from to perform any client specific
        '                               tasks if needed
        cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf read, Nothing) 'continue reading from the stream
    Catch ex As Exception
        Try 'if an error occurs in the reading purpose, we will try to read again to see if we still can read
            Dim sr As New StreamReader(cli.GetStream) 'initialize a new streamreader which will read from the client's stream
            Dim msg As String = sr.ReadLine() 'create a new variable which will be used to hold the message being read
            RaiseEvent gotmessage(msg, Me) 'tell the server a message has been recieved. Me is passed as an argument which represents 
            '                               the current client which it has recieved the message from to perform any client specific
            '                               tasks if needed
            cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf read, Nothing) 'continue reading from the stream
        Catch ' IF WE STILL CANNOT READ
            RaiseEvent disconnected(Me)  'WE CAN ASSUME THE CLIENT HAS DISCONNECTED
        End Try

    End Try
End Sub

I hope I am making sense with all this. It all seems to bounce back and forth, it seems so convoluted.

I've tried using Me.listbox1 and Server.listbox1 and several other similar structures, but to no avail.

I'm reading a lot about Invoke and Delegates, but would that be necessary if the method and the control are in the same class? Or do I have a fundamental misperception of what a class is?

Many thanks for any help I can get.


回答1:


    Private Delegate Sub UpdateListDelegate(byval itemName as string)
    Private Sub UpdateList(byval itemName as string)
    If Me.InvokeRequired Then
        Me.Invoke(New UpdateListDelegate(AddressOf UpdateList), itemName)
    Else
        ' UpdateList
        ' add list add code
        ListBox1.Items.Add(itemName)
    End If
    End Sub

Add above, then replace:

   ListBox1.Items.Add(client.name)

to

   UpdateList(client.name)

Does it work? check the syntax, may have typo as I type it.



来源:https://stackoverflow.com/questions/13072621/vb-net-listbox-items-add-throws-exception-in-same-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!