如何在 VB.NET 中正确使用 ProgressBar

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14578123/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 16:38:14  来源:igfitidea点击:

How to use a ProgressBar properly in VB.NET

vb.net

提问by Wine Too

I have to use a progress bar in my VB.NET programs which behaves very different from those in VB6. For example, if I have a procedure to fill a datagridview through some loop and show that progress with progressbar what happend?
Datagridview fill's 100% while progressbar comes to about 50%!

我必须在我的 VB.NET 程序中使用一个进度条,它的行为与 VB6 中的进度条非常不同。例如,如果我有一个程序通过某个循环填充 datagridview 并使用进度条显示进度,发生了什么?
Datagridview 填充为 100%,而进度条大约为 50%!

Here is example program to illustrate a problem. Create a new project, add a windows form and just copy this code on Form1's code.

这是说明问题的示例程序。创建一个新项目,添加一个 windows 窗体,然后将此代码复制到 Form1 的代码上。

Public Class Form1

Dim myMax As Integer = 100000
Dim pb As New ProgressBar
Dim dgv As New DataGridView
Dim WithEvents ti As New Timer

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    With Me
        .Width = 400
        .Height = 250

        .Controls.Add(pb)
        With pb
            .Maximum = myMax
            .Dock = DockStyle.Bottom
        End With

        .Controls.Add(dgv)
        With dgv
            .ColumnCount = 2
            .Dock = DockStyle.Fill
            .Columns(1).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
            .Visible = False
        End With
    End With

    ti.Start()
End Sub

Private Sub OnFormLoaded(ByVal sender As Object, ByVal e As EventArgs) Handles ti.Tick
    ti.Enabled = False
    ti.Dispose()

    Dim temp As Integer

    For t = 0 To myMax

        If t Mod 100 = 0 Then
            pb.Value = t
            pb.Refresh()
            Application.DoEvents()

            temp += 1

            dgv.Rows.Add(New String() { _
                t.ToString, _
                temp.ToString _
                })
        End If
    Next
    pb.Value = myMax
    pb.Visible = False
    dgv.Visible = True
    dgv.Focus()

End Sub
End Class

This code creates few controls, loads a form and starts a loop to fill data and show that progress in progressbar. After that program hides a progressbar and shows a datagridview what is usual situation in concrete (real-world) programs.

这段代码创建了几个控件,加载了一个表单并启动了一个循环来填充数据并在进度条中显示进度。在该程序隐藏一个进度条并显示一个 datagridview 之后,具体(现实世界)程序中的通常情况。

Problem is that although both, datagridview filling and updating a progressbar goes from same loop (in steps by 100) filling of datagridview ends much faster than progressbar show a progress and hides it on about 50%.

问题是,尽管 datagridview 填充和更新进度条都来自同一个循环(以 100 为步长),但 datagridview 的填充结束速度比进度条显示进度快得多,并将其隐藏在大约 50% 处。

This is much different from VB6 where filling and showing is totally sinchronized and grid will be showed after progressbar reaches value of 100%.

这与 VB6 有很大不同,VB6 的填充和显示完全同步,进度条达到 100% 后才会显示网格。

How to get such functionality of progressbar in VB.NET on showed code?
I try with refresh of progressbar and DoEvents but this is not enough to get it work as expected.

如何在显示的代码上获得 VB.NET 中进度条的这种功能?
我尝试刷新进度条和 DoEvents,但这还不足以使其按预期工作。

采纳答案by Wine Too

In order to solve this problem without to do a "threaded science fiction" from just a ProgressBar you have to use one technique which is often with microsoft's GUI toolkits.

为了解决这个问题,而不是从一个 ProgressBar 做一个“线程科幻小说”,你必须使用一种技术,这种技术通常与微软的 GUI 工具包一起使用。

Such approach can probably solve your concrete problem:

这种方法可能可以解决您的具体问题:

    If t Mod 100 = 0 Then
        pb.Value = t
     If pb.Value > 0 Then pb.Value -= 1

        temp += 1

        dgv.Rows.Add(New String() { _
            t.ToString, _
            temp.ToString _
            })
    End If