can't add to listbox from delegate callback

tnorton

Member
Joined
Sep 28, 2007
Messages
19
Programming Experience
1-3
I have a listbox on form SerialRx, which I am trying to populate with received serial data.
When I Rx serail data, I call a delegate callback called "CallBackSerial" in class "IVComObjects"
From that I am trying to call a sub on Form "SerialRx" to add to the listbox.
The Sub is called correctly with no errors but the data is not added to the listbox.
Any suggestions

VB.NET:
'**********************8
'This  is in DLL class IVComObjects     
        Public Delegate Sub SerialCallback(ByVal sUserPram As String, ByVal mPort As Int16, ByVal mData As String, ByVal nSize As Int16)


Public Sub CallBackSerial(ByVal sUserPram As String, ByVal mPort As Int16, ByVal mData As String, ByVal nSize As Int16)
            Dim mstring As String
            mData = Microsoft.VisualBasic.Left(mData, nSize)
            mstring = sUserPram & vbCrLf & _
                "Com Port " & mPort & vbCrLf & _
                "Data Rx " & mData & vbCrLf & _
                "Characters Rx " & nSize

            SerialRx.DelegateTest(AddressOf SerialRx.AddToList, mData)


        End Sub

'**********************8
'This  is in form class SerialRx
 Public Class SerialRx
    Public Delegate Sub AddRxSerial(ByVal mData As String)

     Sub DelegateTest( _
        ByVal op As AddRxSerial, _
        ByVal y As String _
    )
        op.Invoke(y) ' Call the method.
    End Sub


    Public Sub AddToList(ByVal strData As String)
      '  lstSerialRx.SuspendLayout()
        lstSerialRx.Items.Add(strData)
       ' lstSerialRx.Update()
       ' lstSerialRx.Refresh()
       ' lstSerialRx.ResumeLayout()
    End Sub
End Class
 
It is the control that must invoke the delegate. (if invokerequired for that control)
lstSerialRx.Invoke(op, y)

op.Invoke does call the sub method (just like calling AddToList directly would), but does not delegate the call to the controls thread context.
 
It is the control that must invoke the delegate. (if invokerequired for that control)
lstSerialRx.Invoke(op, y)

op.Invoke does call the sub method (just like calling AddToList directly would), but does not delegate the call to the controls thread context.

I am not fully understanding.

are you saying to change the code like this???
'**********************8
'This is in DLL class IVComObjects
Public Delegate Sub SerialCallback(ByVal sUserPram As String, ByVal mPort As Int16, ByVal mData As String, ByVal nSize As Int16)


VB.NET:
Public Sub CallBackSerial(ByVal sUserPram As String, ByVal mPort As Int16, ByVal mData As String, ByVal nSize As Int16)
            Dim mstring As String
            mData = Microsoft.VisualBasic.Left(mData, nSize)
 //

            SerialRx.DelegateTest(AddressOf SerialRx.AddToList, mData)

        End Sub

'**********************8
'This  is in form class SerialRx
 Public Class SerialRx
    Public Delegate Sub AddRxSerial(ByVal mData As String)

     Sub DelegateTest( _
        ByVal op As AddRxSerial, _
        ByVal y As String _
    )

[COLOR="Red"]lstSerialRx.Invoke(op, y)[/COLOR]
    End Sub


    Public Sub AddToList(ByVal strData As String)
      '  lstSerialRx.SuspendLayout()
        lstSerialRx.Items.Add(strData)
       ' lstSerialRx.Update()
       ' lstSerialRx.Refresh()
       ' lstSerialRx.ResumeLayout()
    End Sub
End Class
 
When you call the Invoke method of a delaget all that does is invoke the method it has a reference to. That's useless if the method access a control and your not on the thread that owns it. As JohnH said, you have to call the Invoke method of the control, NOT the delegate. Your code should have this type of structure:
VB.NET:
Private Delegate Sub MyMethodCallback(ByVal strData As String)

Private Sub MyMethod(ByVal strData As String)
    If myControl.InvokeRequired Then
        myControl.Invoke(New MyMethodDelegate(AddressOf MyMethod), strData)
    Else
        'Access myControl directly here.
    End If
End Sub
So you see, you create a delegate instance with a reference to the current method and call the Invoke method of the control. Internally the control will marshal the call to the thread that owns it and then it will invoke the delegate, which will then execute the method again on the correct thread, thus allowing for direct access to the control.
 
OK, I can get this to work if i put everything in the same class but as soon as I put the callback into another class. I stops working.

it gets to If lstSerialRx.InvokeRequired Then
and jumps straight to the else but does not update the listbox

VB.NET:
    Public Sub MyMethod(ByVal strData As String)
        If lstSerialRx.InvokeRequired Then
            lstSerialRx.Invoke(New MyMethodCallback(AddressOf MyMethod), strData)
        Else
            lstSerialRx.Items.Add(strData)
        End If
    End Sub
 
maybe there's something wrong with your lstSerialRx reference?
 
Back
Top