从类修改表单中的标签和对象 (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)的主要内容,如果未能解决你的问题,请参考以下文章

vb.net动态设置gridview列的属性

如何从类外修改向量

在vb net中,如何猎取和修改已选定的某一项的值?

vb.net,datagridview怎么用?怎么弄成下面的效果?修改和删除怎么弄?

如何通过 VB.NET 修改 XML 中的 CData

vb.net(VS2010) vista下 修改注册表