You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET中Form.Shown先于控件加载,求类似JS window.onload的实现

解决方法

你的问题根源在于Shown事件中同步执行了耗时的循环操作,导致UI线程被阻塞,窗体来不及完成图片和标签的绘制就开始处理循环。要实现类似JavaScript中window.onload的效果,让窗体完全渲染后再启动进度条操作,可以通过以下方式处理:

方法1:使用BeginInvoke延迟执行加载逻辑

通过BeginInvoke将加载代码放到UI线程的消息队列末尾,确保窗体先完成所有绘制操作后再执行循环:

Private Sub FRM_CargaInicial_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
    LBL_Carga.Visible = True
    ' 将加载逻辑放入BeginInvoke,等待UI完成渲染
    Me.BeginInvoke(Sub()
                       Dim Dt As DataTable = New DataTable
                       If conexion.EjecutarSQL("EXEC [GIM_RECURSOS].[IMAGEN].[SP_IMPORTAR]", Dt) Then
                           PRB_Carga.Maximum = Dt.Rows.Count
                           PRB_Carga.Value = 0
                           For Each fila As DataRow In Dt.Rows
                               Iconos.Add(New OBJIcono(fila.Item("ID_INFORMACION"), fila.Item("CLAVE"), fila.Item("VALOR")))
                               PRB_Carga.Value += 1
                               ' 强制刷新进度条,确保实时显示进度
                               PRB_Carga.Refresh()
                           Next fila
                       End If
                       Me.Hide()
                       FRM_Ingreso.Show()
                   End Sub)
End Sub

关键说明

  • BeginInvoke会把传入的委托方法加入UI线程的消息队列,等当前所有待处理的UI消息(比如绘制窗体控件)执行完毕后才会运行,这样就能保证窗体的图片和标签先显示出来。
  • 在循环中调用PRB_Carga.Refresh()可以强制进度条立即重绘,避免因为UI线程繁忙导致进度条一次性填满的问题。

进阶优化(可选)

如果SQL查询或循环操作耗时较长,建议使用后台线程(如Task.Run)来处理,避免阻塞UI线程,同时通过Invoke更新UI控件:

Private Async Sub FRM_CargaInicial_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
    LBL_Carga.Visible = True
    ' 等待UI完成渲染
    Await Task.Delay(10)
    
    Dim Dt As DataTable = Await Task.Run(Function()
                                            Dim table As New DataTable
                                            conexion.EjecutarSQL("EXEC [GIM_RECURSOS].[IMAGEN].[SP_IMPORTAR]", table)
                                            Return table
                                        End Function)
    
    If Dt IsNot Nothing AndAlso Dt.Rows.Count > 0 Then
        PRB_Carga.Maximum = Dt.Rows.Count
        PRB_Carga.Value = 0
        For Each fila As DataRow In Dt.Rows
            Iconos.Add(New OBJIcono(fila.Item("ID_INFORMACION"), fila.Item("CLAVE"), fila.Item("VALOR")))
            ' 在UI线程更新进度条
            Me.Invoke(Sub() PRB_Carga.Value += 1)
        Next fila
    End If
    
    Me.Hide()
    FRM_Ingreso.Show()
End Sub

这个版本使用Async/Await和Task.Run将耗时的SQL查询放到后台线程,UI线程不会被阻塞,窗体渲染和进度条更新会更流畅。

内容的提问来源于stack exchange,提问作者Gus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 00:47:43