从函数的另一个窗口更新ProgressBar?

时间:2011-09-04 23:30:52

标签: c# .net winforms progress-bar

我有一个上传文件的后台任务,我希望它将进度报告给另一个表单上的进度条。我该怎么办?我是C#的新手,但很长时间是VB .net程序员。

我正在搞乱这段代码,但它完全错了。

System.Windows.Forms.Form progForm = new ProgressWindows();
Control[] ctrls = progForm.Controls.Find("fileProgress1", true);

3 个答案:

答案 0 :(得分:2)

如果您使用的是BackgroundWorker,请致电ReportProgress。否则,您需要将UI更改分派给正确的线程。在WinForms中,请参阅Control.InvokeRequired属性和相关方法。 WPF等效值为DispatcherObject.VerifyAccess

编辑:Visual Studio不在我面前,因此可能存在一些小的编译错误。

public partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent(); // fileProgress1 setup. 
    }

    private void StartTask()
    {
        Task t1 = new Task(BackgroundMethod1, fileProgress1); // Explicitly pass a reference to the progress bar.
        Task t2 = new Task(BackgroundMethod2); // Use a method that has access to the bar.
        Task t5 = new Task(BackgroundMethod3, IncrementPBMethod); // Pass an action to the background method. Abstracting the physical progress bar as something where you can set the progress.
        Task t4 = new Task(delegate() { /* fileProgress1 referened*/ }); // Create a closure. I don't recommend this method.
    }

    private static void BackgroundMethod1(ProgressBar pb)
    {
        for(int i = 0; i < 100; ++i)
        {
            if(pb.InvokeRequired)
            {
                pb.Invoke(delegate() { pb.Value = i; });
            }

            Thread.Sleep(1000);
        }
    }

    private void BackgroundMethod2()
    {
        for(int i = 0; i < 100; ++i)
        {
            if(fileProgress1.InvokeRequired)
            {
                fileProgress1.Invoke(delegate() { fileProgress1.Value = i; });
            }

            Thread.Sleep(1000);
        }
    }

    private static BackgroundMethod3(Action<int> setProgress)
    {
        for(int i = 0; i < 100; ++i)
        {
            setProgress(i);
            Thread.Sleep(1000);
        }
    }

    private void IncrementPBMethod(int value)
    {
        if(fileProgress1.InvokeRequired)
        {
            fileProgress1.Invoke(IncrementPBMethod, value);
        }
        else
        {
            fileProgress1.Value = value;
        }
    }
}

答案 1 :(得分:1)

如果您遇到问题只是访问fileProgress1。最简单的解决方案是在ProgressWindow类中公开它。默认情况下,控件是私有的。

enter image description here

然后您可以访问fileProgress1控件,如下所示。

ProgressWindows progForm = new ProgressWindows();
//progForm.fileProgress1 

然而,更好的方法是在PrefressWindows类中公开一个更新进度的公共方法。

在ProgressWindows类中

public void UpdateProgressBar(int percentage)
{
    // Set the progress in the progress bar.
    fileProgress1.Percentage = percentage;
}

请按以下方式调用上述方法。

ProgressWindows progForm = new ProgressWindows();
progForm.UpdateProgressBar(percentage);

答案 2 :(得分:0)

我假设您的第二个表单(您要显示进度的表单)在执行“任务”的表单中实例化。为什么不简单地创建第二种形式的公共方法,除了整数参数以更新进度条值?似乎是一个相对简单的解决方案。