printf printf - 1 month ago 10
Vb.net Question

Changing a Control's property via a delegate

First off, pardon me if my English is bad, I'm not a native English speaker.

I'm fairly new to programming and I'm trying to teach myself VB.NET
I came across a problem while trying to learn about Delegates. (see code below)

What I'm trying to accomplish is to update a specified Control's text property via a thread. However, as soon as I start the thread, I get an ArgumentException Error. I have completely no idea what's wrong. Anybody have an idea what i've done wrong here?

Public Class Form1

Delegate Sub myDelegate1(ByVal s_Name As Control, ByVal s_txt As String)
Public txtUpdate As New myDelegate1(AddressOf upd_ControlTextProperty)

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Label1.Text = vbnullstring
End Sub

Private Sub upd_ControlTextProperty(ByVal ControlName As Control, ByVal txt As String)
ControlName.Text = txt
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim thread1 As New Threading.Thread(AddressOf threadstart)
thread1.IsBackground = True
thread1.Start()

End Sub

Private Sub threadstart()
Me.Invoke(Me.txtUpdate, New Object(), {Label1, "This is Label 1"})
End Sub

End Class

Answer

As TheValyreanGroup said, your delegate is supposed to accept two arguments, and you pass it three :

Me.Invoke(Me.txtUpdate, New Object(), {Label1, "This is Label 1"})
          ^-1--------^  ^-2--------^  ^-3-----------------------^

So just remove the New Object() thing, and transform this {Label1, ...} into just a string :

Me.Invoke(Me.txtUpdate, "This is Label 1")

OK Better that way.

On a second hand, what you are doing is not very usefull.

  • You create a new Thread from your UI Thread.
  • With this new Thread, you invoke back the UI Thread and you stop your Thread...

Remember that a Control can be updated only by the Thread who created the Form (the UI thread).

Unless you have a good reason to work with your background thread, you can resume your code to :

Public Class Form1

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Label1.Text = vbnullstring
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Label1.Text = "This is Label 1"
End Sub

End Class