Question Update RichTextBox with invoke using parameters

ebortoluzzi

Member
Joined
Sep 17, 2009
Messages
8
Programming Experience
Beginner
Hi all

I'm facing the problem of updating a RichTextBox (RTB) from a thread with parameters, I used invoke and methodinvoker:

Private Shared ToBeDisplayed(0) As String

Private Sub TmpBTN_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles TmpBTN.Click
Dim thr As Thread = New Thread(AddressOf Me.testhread)
DisplayRTB.Clear()
thr.Start()
End Sub

Private Sub testhread()
Array.Clear(ToBeDisplayed, 0, ToBeDisplayed.Length)
For i As Integer = 0 To 10
ReDim Preserve ToBeDisplayed(i)
For j As Integer = 0 To i
ToBeDisplayed(i) &= j.ToString
Next
If DisplayRTB.InvokeRequired Then
Invoke(New MethodInvoker(AddressOf FillRTB))
Else
FillRTB()
End If
Next
End Sub

Private Sub FillRTB()
Me.DisplayRTB.Lines = ToBeDisplayed
Me.DisplayRTB.Update()
End Sub


To pass the string array ToBeDisplayed() to the FillRTB I declared them at higher level in the class, because MethodInvoker requires a sub without parameters ?!?

It works but I do not like it :(

I can't believe it is not possible to manage a FillRBT with parameters like:

Private Sub FillRTB(byval MyDisplayed() as string)
Me.DisplayRTB.Lines = MyDisplayed
Me.DisplayRTB.Update()
End Sub


Someone can show/telle me how to proceed, by writing code examples it is the best thank you :rolleyes:
 
You can't use the MethodInvoker delegate if you need to pass parameters or return a value. You need to declare your own delegate. [ame="http://www.vbforums.com/showthread.php?t=498387"]Check this out[/ame] for a full explanation.
 
Hi jm,

I had a quick read to your link it looks like exactly what I was looking for with detailed explanation & examples

I'll try later and let you know, anyhow thanks in advance ;)
 
Hi jm

I tried your topic but it did not work:

VB.NET:
 Private Delegate Sub FillRTBinvoker(ByVal linee() As String)

  Private Sub FillRTB(ByVal linee() As String)

    If Me.DisplayRTB.InvokeRequired Then
      Me.DisplayRTB.Invoke(New FillRTBinvoker(AddressOf FillRTB), linee)
    Else
      Me.DisplayRTB.Lines = linee
    End If

    Me.DisplayRTB.Update()

  End Sub

I got an exception at the invoke, I think ?!? (just a guess) the problem is that "linee" is a string array , while the invoke method needs a paramarray args() as object

:rolleyes:

Ok now it works like if I'm working with .NET 1.x, but I have for sure .NET 2.0 and 3.5
VB.NET:
Private Delegate Sub FillRTBinvoker(ByVal linee() As String)

  Private Sub FillRTB(ByVal linee() As String)

    If Me.DisplayRTB.InvokeRequired Then
      Me.DisplayRTB.Invoke(New FillRTBinvoker(AddressOf FillRTB), New Object() {linee})
    Else
      Me.DisplayRTB.Lines = linee
      Me.DisplayRTB.Update()
    End If

  End Sub
 
Last edited:
Set a breakpoint, so you can advance line-by-line to see where the problem lies. You can place the cursor over different variables/control methods to see their values as well. Especially helpful to use a Try-Catch statement around the code and then you can see the exception itself.
 
Set a breakpoint, so you can advance line-by-line to see where the problem lies. You can place the cursor over different variables/control methods to see their values as well. Especially helpful to use a Try-Catch statement around the code and then you can see the exception itself.
The problem in this case is that the Invoke method takes a delegate and a ParamArray of arguments. If you want to pass an array as the only argument then you can't just pass it as is because it will be taken as multiple distinct arguments rather than a single argument. You need to create an Object array containing your array, so it will be interpreted properly, which is what the OP seems to have done. That's why I think that the problem is solved, but the OP's words are ambiguous.
 
"New Object() {linee}", this is correct, when passing arrays of reference types to Invoke you have to be explicit and wrap the parameter as Object array, else each object in the array will pass as a single param object and you get multiple parameters to a handler that expect only one. A value type array does not cause this "problem".
 
I wrote my post in two steps: the first part which did not work provided to me the error message from which I guessed a problem in the declaration, the invoke was expecting a paramarray of Object

Then in jm link I found the precisation about the 1.x .NET and saw the
VB.NET:
 New Object() {variable,...}
declaration and :) IT WORKS :).

I think jm you should add an Array example to your good [ame="http://www.vbforums.com/showthread.php?t=498387"]explanation [/ame]



Please can you show me how should I have wrote the code using the Array
VB.NET:
dim linee as Array
which should have avoided the
VB.NET:
New Object()  {variable,...}
explicit declaration in the
VB.NET:
Me.DisplayRTB.Invoke(New FillRTBinvoker(AddressOf FillRTB), .....)
 
Last edited:
Set a breakpoint, so you can advance line-by-line to see where the problem lies. You can place the cursor over different variables/control methods to see their values as well. Especially helpful to use a Try-Catch statement around the code and then you can see the exception itself.

Thanks but this is what I did and found the exception in the invoke call, which by chance led to the solution in the end, even if not the nicest that should be with an Array object
 
Yes, you can use an intermediate variable declared as Array or Object and assign the parameter array to that, the same effect is also achieved by casting the array object to type Object when passed to Invoke:
VB.NET:
Me.Invoke(..., CType(arrayObject, Object))
 
Please can you show me how should I have wrote the code using the Array
VB.NET:
dim linee as Array
which should have avoided the
VB.NET:
New Object()  {variable,...}
explicit declaration in the
VB.NET:
Me.DisplayRTB.Invoke(New FillRTBinvoker(AddressOf FillRTB), .....)
There is no way to avoid it and JohnH and I have both explained why already.
 
Back
Top