进度条仅在工作完成后出现?

soo*_*ise 0 c# winforms progress-bar

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

注意:我的代码可能不是100%正确,我只是因为保密原因而试图使它与我自己的不同.

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
    }
}
Run Code Online (Sandbox Code Playgroud)

cas*_*One 6

发生这种情况是因为您在表单Load事件中执行了所有处理.在第一次显示表单之前调用此方法.

在事件处理程序中,您正在阻止表单实际显示,因为事件处理程序必须先完成才能处理其他任何内容.

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

你有一些问题,你的Pizza课程与进度条紧密相连.这不是一个好主意.相反,您应该触发一个事件来指示进度已更改,然后从Pizza实例的事件处理程序中调用ProgressChanged事件.

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

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

这是示例的样子:

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();
}
Run Code Online (Sandbox Code Playgroud)