从类修改表单中的标签和对象 (VB.NET)
Posted
技术标签:
【中文标题】从类修改表单中的标签和对象 (VB.NET)【英文标题】:Modifying Labels and Objects in Forms from Classes (VB.NET) 【发布时间】:2016-05-22 19:07:12 【问题描述】:我有一个类可以获取互联网时间并将其显示在文本框中。这是那个类名InternetTimeGet
我在该类中添加了一个“进度表”,它将显示程序在 IP 列表中的进度。现在调试控制台正在显示这些 IP 和更新,如下所示:IPs and Progress
一切都已经是多线程的,没有任何东西挂在我的 UI 上
但是,我无法让程序在名为 ProgLbl
的标签上显示进度,而我的主窗体名为 MainForm
。这是我的InternetTimeGet
类的代码:
Public Class InternetTimeGet
'Irrelevant variables omitted...
'Used to update progress
Public Shared IPCount As Integer
Public Shared ProgDivision As Single
Public Shared ProgBar As Single
Public Shared FullBar As Integer = 100
IPCount = My.Settings.ServerIPList.Count
ProgDivision = FullBar / IPCount
For Each IP As String In ServArray
Try
'Shows each IP and the Percentage completion in Debug console
Debug.WriteLine(IP, "IP Addresses")
ProgBar = ProgBar + ProgDivision
Debug.WriteLine(Math.Round(ProgBar, 1) & "%", "Progress")
MainForm.ProgLbl.Text = "Progress: " & Math.Round(ProgBar, 1) & "%"
If My.Computer.Network.Ping(IP) Then
LastHost = IP
Result = GetNISTTime(IP)
End If
Catch ex As Exception
'Return "Sync Error 0x01"
MsgBox("There was a sync error while retrieving the updated internet time. Please try again.", MsgBoxStyle.Critical, "Sync Error 0x01")
Debug.WriteLine("There was a sync error while retrieving the updated internet time. Please try again.", "Sync Error 0x01")
End Try
Next
调试控制台显示每个 IP 和完成百分比很好,不显示中间更新或挂起 UI,但我的主窗体 MainForm
中的标签 ProgLbl
不显示这些更新完全没有,只是说“进度:”。再次我的主窗体MainForm
的用户界面不会挂起。
问题是从上面显示的InternetTimeGet
类更新我的主要形式MainForm
中的标签ProgLbl
。这就是我希望提供的帮助。
我一直在寻找答案并尝试了几件事,但最终放弃了,并决定问那些更了解的人。
感谢您的帮助
【问题讨论】:
我想 MainForm 是类名而不是你的主窗体实际显示的实例,对吧? 该代码在哪里?你看到最后一个消息(大概是“100%”)吗?它可能正在工作,但您只是看不到任何中间更新。再一次,它可能与默认表单实例有关(如果MainForm
是类名而不是实例名)。
第一行...“我有一个类可以获取互联网时间并将其显示在文本框中”,这段代码显然是在拉动互联网时间。这是该类的代码。 MainForm
是项目的主要形式。在MainForm
中有一个名为 ProgLbl 的标签。我正在尝试让此类将进度更新发送到该标签。就目前而言,IP 和进度更新在调试控制台中显示良好,不,它们没有挂起 UI,因为我已经对所有内容进行了多线程处理
我已经更新了原始帖子,以便更清楚地了解我需要帮助的内容。谢谢
MainForm
听起来像是表单的类名。这意味着您正在使用可能是问题的默认表单实例。然后创建或获取表单instance,而不是摆弄其他类中的控件,而是创建一个方法来允许其他参与者将数据传递给它。表单可以更新控件本身。
【参考方案1】:
好吧,不清楚您的代码是在哪里实现的,但如果您想进行一些操作(例如获取时间和浏览 IP 列表),作为一般规则,您会希望避免这样做在主线程中以避免冻结 UI。
后台工作人员非常适合这种用途,因为它允许您在报告进度的同时运行代码异步,以便您可以更新主表单。
这是一个使用后台工作者的简单示例 您将不得不返工以满足您的需要。
Private WithEvents _GetTimeWorker As BackgroundWorker
在表单中的某个地方,您需要初始化您的工作人员并将 WorkerReportProgress 设置为 true。然后,您可以在需要时启动工作程序。
Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
_GetTimeWorker = New BackgroundWorker With .WorkerReportsProgress = True
_GetTimeWorker.RunWorkerAsync()
End Sub
DoWork 实际上是您将逻辑放入其中的异步方法,因此它不会阻塞 UI。当您想要更新进度条时,您可以在后台工作人员上调用 ReportProgress。
Private Sub _GetTimeWorker_DoWork(sender As Object, e As DoWorkEventArgs) Handles _GetTimeWorker.DoWork
Dim watch As New Stopwatch
watch.Start()
'Just simulating some work.
While watch.ElapsedMilliseconds < 10000
System.Threading.Thread.Sleep(100)
_GetTimeWorker.ReportProgress(CInt(watch.ElapsedMilliseconds / 10000 * 100))
End While
End Sub
进度条值从进度更改函数更新。
Private Sub _GetTimeWorker_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles _GetTimeWorker.ProgressChanged
'There we change the progress bar value
prog1.Value = e.ProgressPercentage
End Sub
【讨论】:
我已经更新了帖子,以便更清楚地了解我正在寻求帮助的内容。我不需要线程或挂起 UI 的帮助,因为我已经彻底地多线程了这个程序。什么都挂着。无论如何,谢谢你,但如果你能重新阅读 OP 并相应地重新回答,我将不胜感激 这是一个很好的解决方案,而且写得很好。我喜欢 BackgroundWorker 如何简化所有这些,但我仍然相信创建委托和编写方法来检查它们是否需要被调用是更好的解决方案。主要是因为您可以随时运行任何异步方法。我写了一个例子来回答另一个问题。 ***.com/questions/37330987/…以上是关于从类修改表单中的标签和对象 (VB.NET)的主要内容,如果未能解决你的问题,请参考以下文章