进度条只在工作完成后出现? [英] Progress Bar Only Appears After Work Is Complete?

查看:61
本文介绍了进度条只在工作完成后出现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在表单上显示进度条,但由于某种原因,该表单在流程结束之前实际上并不可见,并且在流程结束时关闭(或者换句话说,表格只打开一瞬间).我如何才能使表单在流程开始时显示?

I'm trying to make a progress bar show up on a form, but for some reason the form isn't actually visible until the process is over, and it is closed when the process is over (or in other words, the form is only open for an instant). How can I make it so the form shows up at the beginning of the process?

注意:我的代码可能不是 100% 正确的,出于保密原因,我只是想让它与我自己的不同.

Note: my code might not be 100% correct, I'm just trying to make it different than my own for confidentiality reasons.

public void SpawnPizzaProgressBarForm(object sender, EventArgs e)
{
    FormPizzaProgressBar Form = new FormPizzaProgressBar();
    Form.ShowDialog();
}
...
public void ProgressBarForm_Load(object sender, EventArgs e)
{
    Pizza = new Pizza();
    Pizza.Eat(PizzaEatingProgressBar);
    this.Close();
}
...
public void Eat(ProgressBar PizzaEatingProgressBar)
{
    foreach(var Slice in Pizza)
    {
        Slice.Clear(); //
        PizzaEatingProgressBar.Value = (Slice.Index / Pizza.Count())*100
    }
}

推荐答案

发生这种情况是因为您在 加载表单事件.这被称为之前表单第一次显示.

This happens because you do all the processing in the Load event for the form. This is called before the form is shown for the first time.

在事件处理程序中,您阻止了表单的实际显示,因为事件处理程序必须在处理其他任何事情之前完成.

While in the event handler, you are preventing the form from actually showing, as the event handler has to complete before anything else can be processed.

您想要做的是使用 BackgroundWorker 实例来执行您的工作.这需要您执行以下操作:

What you want to do is use a BackgroundWorker instance to perform your work. This requires you to do the following:

  • Create the instance of the BackgroundWorker
  • Set the WorkerSupportsProgress property to true (the default is false)
  • Subscribe to the DoWork event
  • In the DoWork event handler, make calls to the ReportProgress method to report your progress
  • Subscribe to the ProgressChanged event, this is where you will update your progress bar. This is also the event htat is fired when you call the ReportProgrss method mentioned before
  • Subscribe to the RunWorkerCompleted event, this is where you will close your form when done
  • Call the RunWorkerAsync method to start the asynchronous operation

您在这里遇到了一些问题,因为您的 Pizza 类与进度条紧密耦合.这不是个好主意.相反,您应该触发一个事件以指示进度已更改,然后从 Pizza 实例的事件处理程序中调用 ProgressChanged 事件.

You have some issues here in that you have your Pizza class tightly coupled to the progress bar. This isn't a good idea. Rather, you should have an event that is fired to indicate that the progress has changed, and then call the ProgressChanged event from the event handler for your Pizza instance.

我已经移出了 Eat 方法的代码并将其封装在表单中,以向您展示如何使用 BackgroundWorker 类的示例,但理想的解决方案是公开一个事件以指示披萨的数量消耗的变化.

I've moved out the code for your Eat method and encapsulated it in the form to show you an example of how to use the BackgroundWorker class, but the ideal solution would be to expose an event to indicate when the amount of pizza consumed changes.

另请注意,您应该覆盖表单类上的 受保护的 Dispose 方法 在处理表单时正确处理 BackgroundWorker 实例.

Also note that you should override the protected Dispose method on the Form class to properly dispose of the BackgroundWorker instance when the form is disposed of.

示例如下:

public void SpawnPizzaProgressBarForm(object sender, EventArgs e)
{
    FormPizzaProgressBar Form = new FormPizzaProgressBar();
    Form.ShowDialog();
}

...

BackgroundWorker worker = new BackgroundWorker();

public void ProgressBarForm_Load(object sender, EventArgs e)
{
    // Initialize the background worker.
    worker = new BackgroundWorker();

    // Indicate that the worker supports progress.
    worker.WorkerSupportsProgress = true;

    // Subscribe to the DoWork event.
    worker.DoWork += (s, e) => {
        // Create the pizza instance.
        Pizza = new Pizza();

        // Process the slices.
        foreach (var Slice in Pizza)
        {
            // Clear the slice.
            Slice.Clear();

            // Report the progress.
            worker.ReportProgress(Slice.Index / Pizza.Count() * 100);
        }
    };

    // Subscribe to the ProgressChanged event.
    worker.ProgressChanged = (s, e) => {
        // Update the progress bar.
        PizzaEatingProgressBar.Value = e.ProgressPercentage;
    };

    // Subscribe to the RunWorkerCompleted event.
    worker.RunWorkerCompleted = (s, e) => {
        // Close the dislog.
        this.Close();
    };
}

// Must override to properly dispose of the background worker.
protected override void Dispose(bool disposing)
{
    // Call the base.
    base.Disposing(disposing);

    // Dispose of the background worker if disposing is true.
    if (disposing) worker.Dispose();
}

这篇关于进度条只在工作完成后出现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆