为其他类控制Windows窗体对象

时间:2013-10-04 15:19:55

标签: c#

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

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

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

现在在ProcessFile方法中,我想控制我的表单中的ProgressBar。 如果我将ProgessBar设为公共和静态,它就可以工作。但这有一些不满。您无法再控制“表单设计器”中的元素。

如果我只能访问我的Form的实例对象,那将很容易。但是我不知道自从表单初始化后如何:

Application.Run(new Form1());

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

是否有另一种/最佳方法从另一个类中控制此ProgressBar?

4 个答案:

答案 0 :(得分:1)

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

MapFiles.ProcessFile(progressBar1);

然后您可以从班级访问它,例如:

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

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

答案 1 :(得分:0)

如果您不想绕过传递表单的引用,可以制作类似的内容。

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

在你的表单加载事件中

FormSharer.Form = this;

并且您可以从其他所有类中引用FormSharer.Form

话虽如此,这样做并不是一个好主意。但是你又需要它,就是这样。

答案 2 :(得分:0)

只要您在同一个项目中的课程可以这样做:

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);

    }

}

我更新了我的答案,因此您无需公开控制

答案 3 :(得分:0)

您可以使用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并在调用progress改变事件时使用它,因此即使您调用{{{{}}也可以在UI线程中触发该事件1}}来自其他一些帖子。