Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
233 views
in Technique[技术] by (71.8m points)

how to do rename the label name from 1 to 75 at run time in vb.net?

Public Sub Rename(ByVal labelno As Integer)
    Try
        Dim lbl As New Label
        lbl = Controls("Label" & labelno.ToString())
        lbl.Text = ReceivedFrame.ToString()
    Catch ex As Exception
        MessageBox.Show(ex.Message.ToString())
    End Try

i want to change Label Text from 1 to 50. Label no given as input. i tried the above code. its working in other project. but in my current project it is not working Error is showing like this (cross Thread operation not valid.control label1 accessed from a thread.other than the thread it was created on)and i want to change the label text only.label&Label no is working properly i verified. is there any other way to rename label in vb.net?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are trying to modify a property of a control which resides on a different thread than the thread from which you call Rename(). When updating controls you should check if it is required to send the call to the appropriate thread, or "invoke" the call. This should work.

Method 1: Always Invoke

Public Sub Rename(ByVal labelno As Integer)
    Try
        Dim lbl As New Label
        lbl = Controls("Label" & labelno.ToString())
        lbl.Invoke(Sub() lbl.Text = ReceivedFrame.ToString())
    Catch ex As Exception
        MessageBox.Show(ex.Message.ToString())
    End Try
End Sub

It will always invoke the call, which is unnecessarily costly when Rename() is called from the control's thread. But it should always work. You can also do it this way to only invoke when required as not to make unnecessary invocations to the UI thread.

Method 2: Invoke only if required

Public Sub Rename(ByVal labelno As Integer)
    Try
        Dim lbl As New Label
        lbl = Controls("Label" & labelno.ToString())
        changeLabelText(lbl, ReceivedFrame.ToString())
    Catch ex As Exception
        MessageBox.Show(ex.Message.ToString())
    End Try
End Sub

Private Delegate Sub changeLabelDel(lbl As Label, txt As String)

Private Sub changeLabelText(lbl As Label, txt As String)
    If lbl.InvokeRequired Then
        lbl.Invoke(New changeLabelDel(AddressOf ChangeLabelText), lbl, txt)
    Else
        lbl.Text = txt
    End If
End Sub

Oh, one more thing. You can automate the whole invoke required check for future use. Put the extension method in a module

Method 3: Automate the invoke required pattern, reusable code

<Extension() _
Public Sub InvokeIfRequired(ByVal c As Control, mi As MethodInvoker)
    If c.InvokeRequired Then
        c.Invoke(mi)
    Else
        mi()
    End If
End Sub

And call it like this:

Public Sub Rename(ByVal labelno As Integer)
    Try
        Dim lbl As New Label
        lbl = Controls("Label" & labelno.ToString())
        lbl.InvokeIfRequired(Sub() lbl.Text = ReceivedFrame.ToString())
    Catch ex As Exception
        MessageBox.Show(ex.Message.ToString())
    End Try
End Sub

There's a wealth of information on this site regarding this topic. See

What does 'InvokeRequired' and 'Invoke' mean in .Net?

VB.net, Invoke, delegates, and threading. Can't figure out how to use them across classes


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...