通过委托更改Control的属性

时间:2016-11-05 11:52:51

标签: vb.net

首先,请原谅我,如果我的英语不好,我不是母语为英语的人。

我对编程很新,我正在尝试自学VB.NET 我在尝试了解代表时遇到了一个问题。 (见下面的代码)

我想要完成的是通过线程更新指定的Control的文本属性。但是,一旦我启动该线程,我就会收到ArgumentException错误。我完全不知道出了什么问题。有谁知道我在这里做错了什么?

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

2 个答案:

答案 0 :(得分:2)

正如TheValyreanGroup所说,你的代表应该接受两个论点,你把它传给三个:

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

所以只需删除New Object()内容,然后将此{Label1, ...}转换为字符串:

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

好的那样。

另一方面,你所做的并不是很有用。

  • 您可以从UI线程创建一个新线程。
  • 使用这个新线程,您可以调用UI线程并停止线程...

请记住,Control只能由创建表单的线程(UI线程)更新。

除非您有充分理由使用后台主题,否则您可以将代码恢复为:

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

<强>更新 (来自评论)

为了更清楚,这里是一个模式(我在https://androidkennel.org/android-networking-tutorial-with-asynctask/上采用,如果有任何限制,我将删除图像)

UI Thread and Background Thread

主UI线程用于:

  • 对用户事件(点击,输入......)做出反应并启动将执行该过程的后台线程
  • 在后台线程结束时或在任务期间更新用户界面。

当我说你正在做的事情没有用时,因为你的后台线程没有做任何处理,它只是通知UI线程来更新UI ......

答案 1 :(得分:0)

我会尝试这种方法。可以从UI线程或新线程成功调用upd_ControlTextProperty。

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 = ""
End Sub

Private Sub upd_ControlTextProperty(ByVal ControlName As Control, ByVal txt As String)
    If Me.InvokeRequired = True Then
        Me.Invoke(txtUpdate, New Object() {ControlName, txt})
    Else
        ControlName.Text = txt
    End If
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()
    upd_ControlTextProperty(Label1, "This is Label 1")
End Sub

End Class