授予其他类对 Windows 窗体对象的控制权

本文关键字:窗体 对象 控制权 Windows 其他 | 更新日期: 2023-09-27 18:33:52

我正在寻找从另一个类控制我的Windows窗体对象的最佳方法。请不要回答,如果你的答案是"这不是你在 OOP 语言中这样做的方式!请照顾我需要的东西:

我的 Windows 窗体中有一个不可见的进度条。如果我按下 Windows 窗体上的按钮,应该加载一个文件,进度条应该执行一些步骤...由于文件加载操作非常复杂,我从自己的类加载它,该类适用于某种类型的文件。喜欢:

void TestButton_Click(object sender, EventArgs e)
{
MapFiles.ProcessFile()
}

现在在进程文件方法中,我想控制窗体中的进度条。如果我使ProgessBar公开和静态,它就可以工作。但这有一些委屈。您无法再在窗体设计器中控制该元素。

如果我可以访问我的表单的实例化对象,那将很容易。但我不知道如何,因为表单是用以下方式初始化的:

Application.Run(new Form1());

我不想在这里对继承做一些事情,因为 MapFiles 实际上与 Form1 没有任何关系......

有没有另一种/最好的方法可以从另一个类控制这个进度条?

授予其他类对 Windows 窗体对象的控制权

为什么不将对进度条的引用传递到ProcessFile方法中:

MapFiles.ProcessFile(progressBar1);

然后,您可以从类中访问它,例如:

ProcessFile(ProgressBar progressBar1)
{
    progressBar1.Value = 0;
}

注意:正如您所说,这可能不是最好的方法。但是您已经明确了您的具体要求,因此这是我的建议,让您的班级控制进度条

如果你不想四处传递对表单的引用,你可以做这样的事情。

public static class FormSharer
{
   public static YourFormClass Form {get; set;}
}

在您的表单加载事件中,您执行

FormSharer.Form = this;

从所有其他类中,您只需引用FormSharer.Form

话虽如此,这样做不是一个好主意。但话又说回来,你需要它,所以就是这样。

只要

你的类在同一项目中,你就可以这样做:

public class Class1
{
    public void AccessForm() 
    {
       var thatForm = (Form1)Form.ActiveForm;
        var progressBar = thatForm.Controls.Cast<Control>().Where(a => a.Name =="progressBar1").FirstOrDefault();
        MessageBox.Show(progressBar.Name);
    }
}

我更新了我的答案,因此您不必公开任何控件

您可以使用 Progress 类非常有效地处理此问题。

只需在单击处理程序中定义一个Progress对象,在该对象中指示如何更新进度;在本例中,通过更新进度栏的值。

然后将该Progress实例*as an IProgress 的实例*传递给您的工作人员。

然后,工作人员可以使用Report来指示进度。

private void button1_Click(object sender, EventArgs e)
{
    Progress<int> progress = new Progress<int>(
        percent => progressbar1.Value = percent);
    DoStuff(progress);
}
private void DoStuff(IProgress<int> progress)
{
    Task.Run(() =>
    {
        for (int i = 0; i < 100; i++)
        {
            progress.Report(i);
            Thread.Sleep(200); //placeholder for real work
        }
    });
}

最棒的是,Progress类甚至可以捕获当前SynchronizationContext并在调用进度更改事件时使用它,因此即使您从其他线程调用Report,该事件也将能够在 UI 线程中触发。