1

我的应用程序运行文件,每个文件都有自己的运行时间。此函数以毫秒为单位获取进度时间应运行的时间:

timerProgress = my timer
pbStatus = my progress bar

public void AnimateProgBar(int milliSeconds)
{
    if (!timerProgress.Enabled && milliSeconds != 0)
    {
        pbStatus.Value = 0;;
        timerProgress.Interval = milliSeconds / 100;
        timerProgress.Enabled = true;
    }
}

这是我填充进度条的计时器:

   private void timerProgress_Tick(object sender, EventArgs e)
    {
        if (pbStatus.Value < 100)
        {
            pbStatus.Value += 1;
            pbStatus.Refresh();
        }
        else
        {
            timerProgress.Enabled = false;
        }
    }

我的问题是进度条运行得太快,例如,如果 AnimateProgBar 的值为 12000(12 秒),进度条只运行 6-7 秒。

4

3 回答 3

3

您的代码不起作用,这很可疑。我试了几次,每次都错过了大约0.6秒;似乎计时器只是不精确

您可以做的是自己处理时间而不是信任计时器:

WithEvents Tmr As New Timer With {.Interval = 100}
Dim startTime As Date, AnimationTime%

Sub AnimateProgress(ms%)
    If ms <= 0 Then Exit Sub

    ProgressBar1.Value = 0
    AnimationTime = ms
    startTime = Now

    Tmr.Start()
End Sub

Private Sub Tmr_Tick() Handles Tmr.Tick
    ProgressBar1.Value = Math.Min((Now - startTime).TotalMilliseconds / AnimationTime, 1) * 100
    If ProgressBar1.Value = 100 Then Tmr.Stop()
End Sub

编辑 - 回复下面的回复:

哦,对不起,不,它是 vb.net。我也知道这两种语言,但我更喜欢 vb,并且倾向于认为其他所有小马也都这样做。

这是c#版本:

DateTime startTime; int animationTime;

void AnimateProgress(int ms) {
    if (ms <= 0) return;

    progressBar1.Value = 0;
    animationTime = ms;
    startTime = DateTime.Now;

    Tmr.Start();
}

private void Tmr_Tick(object sender, EventArgs e) {
    progressBar1.Value = (int)(Math.Min((DateTime.Now - startTime).TotalMilliseconds / animationTime, 1) * 100);
    if (progressBar1.Value == 100) Tmr.Stop();
}
于 2013-04-20T16:02:44.213 回答
0

您可以尝试使用此示例,基于PerformStep method

var progressBar = new System.Windows.Forms.ProgressBar();
progressBar.Maximum = 100;
progressBar.Minimum = 0;
progressBar.Step = 10;

//begin loop

//Your treatment of step 
progressBar.PerformStep();

//end loop

msdn 链接: http: //msdn.microsoft.com/fr-fr/library/system.windows.forms.progressbar.performstep (v=vs.80).aspx

你有样品在这里

private void CopyWithProgress(string[] filenames)
{
    // Display the ProgressBar control.
    pBar1.Visible = true;
    // Set Minimum to 1 to represent the first file being copied.
    pBar1.Minimum = 1;
    // Set Maximum to the total number of files to copy.
    pBar1.Maximum = filenames.Length;
    // Set the initial value of the ProgressBar.
    pBar1.Value = 1;
    // Set the Step property to a value of 1 to represent each file being copied.
    pBar1.Step = 1;

    // Loop through all files to copy.
    for (int x = 1; x <= filenames.Length; x++)
    {
        // Copy the file and increment the ProgressBar if successful.
        if(CopyFile(filenames[x-1]) == true)
        {
            // Perform the increment on the ProgressBar.
            pBar1.PerformStep();
        }
    }
}

链接: http: //msdn.microsoft.com/fr-fr/library/system.windows.forms.progressbar.performstep (v=vs.80).aspx

于 2013-04-20T15:30:22.233 回答
0

我无法重现您的问题。我刚刚测试了一个新表单,其中包含您在问题中详述的 ProgressBar 和 Timer,并且仅添加了一个按钮来开始测试,并添加了一个标签来显示经过的时间:

    DateTime start;
    private void button1_Click(object sender, EventArgs e)
    {
        start = DateTime.Now;
        AnimateProgBar(12000);
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        label1.Text = DateTime.Now.Subtract(start).TotalSeconds.ToString();
        //the rest of your code, starting with "if (pbStatus.Value < 100)"

我一直有 12.6 秒,直到进度条填满(计时器停止,冻结标签文本)......也许你的进度条的一部分被隐藏了?

[编辑] 如果您对 BlackCap 还注意到的 0.6 额外秒感到好奇,那是因为您将计时器间隔设置为 120 毫秒,但计时器事件的分辨率约为 18 毫秒,因此它实际上会在 126 处触发120 个。

于 2013-04-21T12:09:58.423 回答