Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在Winform 2019中从一系列内部方法更新进度条_C#_Winforms - Fatal编程技术网

C# 如何在Winform 2019中从一系列内部方法更新进度条

C# 如何在Winform 2019中从一系列内部方法更新进度条,c#,winforms,C#,Winforms,我在主窗体中有一个进度条,其中有一个名为MethodA()的方法。在这个methodA()的内部,它调用另一个方法Class1.MethodB(),在这个MethodB()的内部,它调用另一个方法Class2.MethodC()。这个MethodC()调用另一个方法Class3.MethodD()。在所有这些方法中,一些长期运行的过程正在进行: class MainForm : Form { void MethodA() { // ... ins

我在主窗体中有一个进度条,其中有一个名为
MethodA()
的方法。在这个
methodA()
的内部,它调用另一个方法
Class1.MethodB()
,在这个
MethodB()
的内部,它调用另一个方法
Class2.MethodC()
。这个
MethodC()
调用另一个方法
Class3.MethodD()
。在所有这些方法中,一些长期运行的过程正在进行:

class MainForm : Form
{
    void MethodA()
    {
        // ...

        instanceOfClass1.MethodB();

        // ...
    }
}

class Class1
{
    void MethodB()
    {
        // ...

        instanceOfClass2.MethodC();

        // ...
    }
}

class Class2
{
    void MethodC()
    {
        // ...

        instanceOfClass3.MethodD();

        // ...
    }
}
方法调用都是实例方法调用,而不是静态调用

如何在此处更新进度条值?。当按钮单击时,进度条应运行并在
Class3.MethodD()
停止执行时结束


我们如何从其他类更新主窗体中的进度条?我无法创建主窗体的实例并将其作为参数传递给每个类。主窗体中还有许多其他控件。

前提是您可以修改其他方法以更改其参数,然后传递
i程序。(虽然
T
是任意的,但是如果您只想更新进度条显示,请使用
i进度
,值
0-1.0
表示0到100%)

避免使用
静态
对象、方法或状态在程序内部传输进度信息

大概是这样的:

class MainForm
{
    private class MainFormProgress : IProgress<Single>
    {
        private readonly ProgressBar pb;
        private const Int32 _max = 10000; // Using values above 100 animate smoother if the ProgressBar is wider than 100 pixels.

        public MainFormProgress( ProgressBar pb )
        {
            this.pb = pb ?? throw new ArgumentNullException(nameof(pb));
            this.pb.Minimum =    0;
            this.pb.Maximum = _max;
            this.pb.Value   =    0;
        }

        public void Report( Single value )
        {
            // You MAY need to wrap this in a call to BeginInvoke or Invoke if this is being run on a background thread.
            this.pb.Value = (Int32)( value * _max );
        }
    }

    void MethodA()
    {
        MainFormProgress progress = new MainFormProgress( this.progressBar );

        instanceOfClass1.MethodB( progress  );

        // ...
    }
}

class Class1
{
    void MethodB( IProgress<Single> progress )
    {
       // ...

        // do something

        progress.Report( 0.1 ); // we're 10% complete!

        instanceOfClass2.MethodC( progress );

        progress.Report( 0.75 ); // we're 75% complete!

        // ...
   }
}

// etc for the other classes
class主窗体
{
私有类MainFormProgress:IProgress
{
私有只读ProgressBar pb;
private const Int32 _max=10000;//如果ProgressBar的宽度大于100像素,则使用大于100的值可以使动画更平滑。
公共MainFormProgress(ProgressBar pb)
{
this.pb=pb??抛出新的ArgumentNullException(nameof(pb));
该最小值=0;
this.pb.max=_max;
此.pb.Value=0;
}
公共作废报告(单值)
{
//如果在后台线程上运行,您可能需要将其包装在对BeginInvoke或Invoke的调用中。
this.pb.Value=(Int32)(值*_max);
}
}
void MethodA()
{
MainFormProgress progress=新的MainFormProgress(this.progressBar);
InstanceOffClass1.MethodB(进度);
// ...
}
}
一班
{
无效方法B(i进度)
{
// ...
//做点什么
进度。报告(0.1);//我们完成了10%!
InstanceOffClass2.MethodC(进度);
进度。报告(0.75);//我们完成了75%!
// ...
}
}
//等其他课程

IProgress
也可用于其他上下文,例如控制台模式应用程序和ASP.NET中的信号器。

通过发送一些允许此操作的接口。。。fx
interface-IProgress{SetProgress(..)}
然后让fx表单实现这个接口,并将表单发送到classx什么方法实际完成了工作,并且能够评估有多少进展?@PatrickTucci感谢您的回复。实际上,所有的方法(methodA,methodB,methodC,methodD)都能完成这项工作,并且在所有这些方法中都有一些长期运行的工作。因此,进度条值必须在所有这些方法中更新。所有这些独立(void)方法如何知道要报告哪种进度?这些方法对同一对象有效吗?这一进展是否可以被视为是一致的(在一组共同的对象上进行的坚定、渐进的工作)?在某些情况下,每个方法都需要单独设置一个
ProgressBar.Value
。所有方法都知道需要设置什么值吗?