无法从另一个线程更改标签文本 [英] Can't change label text from another thread
问题描述
大家好,
我需要在应用程序中更改标签值,我需要从另一个线程执行此操作。这是一个例子: Form1 是我的主要形式, CheckState 是在差异线程中执行的子。
公开 Sub Form1_Load(发件人作为 Object ,e As EventArgs)句柄 Form1.Load
Dim T 作为 新线程( AddressOf CheckState())
T.IsBackground = False
T.开始()
结束 Sub
公共 Sub CheckState()
如果 My.Settings.Enabled 然后
Form1.Label7.Text = 已启用
其他
Form1.Label7.Text = 已禁用
结束 如果
结束 Sub
此代码的问题在于它什么都不做......标签文本没有改变,程序报告没有错误或异常。让我们尝试使用调用:
' Form1_Load中的代码是相同的。
公共 Sub CheckState()
如果 My.Settings.Enabled 那么
Form1.Invoke ( Sub ()Form1.Label7.Text = 已启用)
否则
Form1.Invoke( Sub () Form1.Label7.Text = 已禁用)
结束 如果
结束 Sub
抛出 InvalidOperationException :
Invoke或者,在创建窗口句柄之前,无法在控件上调用BeginInvoke。
我不知道我做错了什么,所以请帮助我!
FWhite
您可能需要调用Form.Show
在Form.Load
事件处理程序中启动线程之前的方法,请参阅此文章:表单初始化,加载和激活事件之间的差异 [ ^ ]。
作为解决方案1的补充,或者可能将线程开始移动到< a href =https://msdn.microsoft.com/en-us/library/system.windows.forms.form.shown(v=vs.110).aspx>显示 [ ^ ] event。
CheckState
子项从模块移动到Main表单类并且它工作正常。我的代码现在看起来像这样:
公共 Class Form1
公开问题 As ProblemType
Dim 订阅作为 字符串 =
私人 Sub Form1_Load(发件人作为 对象,e 正如 EventArgs)句柄 MyBase .Load
我 .BackgroundImage = My.Resources.wall
结束 Sub
私人 Sub Form1_Shown(发件人作为 对象 ,e As EventArgs)句柄 我。显示
Dim T 作为 新 Threading.Thread( AddressOf DecryptSub)
T.IsBackground = False
T .Start()
Dim TR As New Threading.Thread( AddressOf CheckState)
TR.IsBackground = False
TR.Start()
' CheckState()现在是Form1,而不是Core(模块) )。这种方式有效!
如果 My.Settings.Enabled 那么
我 .Invoke( Sub ()我 .Label1.Text = 已启用)
否则
我 .Invoke( Sub ()我 .Label1.Text = 已禁用)
结束 如果
结束 Sub
结束 班级
我真的不明白为什么但重要的是它是工作!
感谢大家!
Hi all,
I need to change a label value in my application and I need to do this from another thread. Here's an example: Form1 is my main form and CheckState is the sub executed in a differend thread.
Public Sub Form1_Load(sender As Object, e As EventArgs) Handles Form1.Load
Dim T As New Thread(AddressOf CheckState())
T.IsBackground = False
T.Start()
End Sub
Public Sub CheckState()
If My.Settings.Enabled Then
Form1.Label7.Text = "Enabled"
Else
Form1.Label7.Text = "Disabled"
End If
End Sub
The problem with this code is that it simply does nothing... The label text is not changed and the program reports no errors or exceptions. Let's try to use Invoke:
'The code in the Form1_Load is the same.
Public Sub CheckState()
If My.Settings.Enabled Then
Form1.Invoke(Sub() Form1.Label7.Text = "Enabled")
Else
Form1.Invoke(Sub() Form1.Label7.Text = "Disabled")
End If
End Sub
An InvalidOperationException is thrown:
Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
I don't know what I'm doing wrong, so please help me!
FWhite
You probably have to call theForm.Show
methos before starting your thread in theForm.Load
event handler, see this article: "Differences Among Form's Initialize, Load, and Activate Events"[^].
As addition to solution 1, or perhaps move the thread start even to Shown[^] event.
This is incredibly strange. I moved theCheckStatesub from the module to the Main form class and it worked. My code now looks like this:
Public Class Form1 Public Problem As ProblemType Dim Subscription As String = "" Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Me.BackgroundImage = My.Resources.wall End Sub Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown Dim T As New Threading.Thread(AddressOf DecryptSub) T.IsBackground = False T.Start() Dim TR As New Threading.Thread(AddressOf CheckState) TR.IsBackground = False TR.Start() 'CheckState() is now in Form1, not in Core (the module). This way it worked! If My.Settings.Enabled Then Me.Invoke(Sub() Me.Label1.Text = "Enabled") Else Me.Invoke(Sub() Me.Label1.Text = "Disabled") End If End Sub End Class
I really can't understand why but the important thing is that it worked!
Thanks to everyone!
这篇关于无法从另一个线程更改标签文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!