将父表单传递给从类实例调用的ShowDialog

Jon*_*Jon 6 .net c# multithreading winforms

我有一张表格.

在那种形式中,我在新线程上创建一个类的实例,因为它运行一些长时间运行的逻辑.该表单还使用户能够取消此逻辑/线程.

如果需要输入,该类将打开一个新表单.

新表单有时会出现在另一个表单后面.

我在课堂上设置了一个属性:

public Form ParentForm{get;set;}
Run Code Online (Sandbox Code Playgroud)

我现在可以这样做:

MyForm form = new MyForm();
form.ShowDialog(ParentForm);
Run Code Online (Sandbox Code Playgroud)

但是在调用时我得到了一个跨线程异常ShowDialog(ParentForm).

我知道我可以用InvokeRequired某种方式但不确定如何在财产上.

谢谢

更新:尝试过这样做但仍然有异常:

MyForm form = new MyForm();
form.ShowDialog(GetParentForm()); 



private Form GetParentForm()
{
    //You have to Invoke() so you can wait for the function to return and obtain its return value.
    if (ParentForm.InvokeRequired)
    {
        return (Form)ParentForm.Invoke(new Func<Form>(() => GetParentForm()));
    }
    else
    {
        return ParentForm;
    } 
}
Run Code Online (Sandbox Code Playgroud)

Mus*_*sis 1

您更新的方法 ( GetParentForm) 将不起作用,因为您将获取引用的任务包装ParentForm在一个InvokeRequired块中。您可以尝试将调用ShowDialog包装在这样的块中,但我认为您仍然会遇到跨线程错误。

最简单的解决方法是将创建和显示第二种形式的代码从类中移出并移至ParentForm. 所以代替这个:

MyForm form = new MyForm();
form.ShowDialog(ParentForm);
Run Code Online (Sandbox Code Playgroud)

你会这样做:

ParentForm.showMyNewForm();
Run Code Online (Sandbox Code Playgroud)

ParentForm会得到这个:

public void showMyNewForm()
{
    MyForm form = new MyForm();
    form.ShowDialog(this);
}
Run Code Online (Sandbox Code Playgroud)

如果MyForm需要在另一个线程上引用该类,您只需添加一个参数,showMyNewForm()以便可以传入对该类的引用。

您在这里尝试做的事情(创建并显示在不同线程上创建的相关的、连接的表单)确实违背了表单在 .NET 中的使用方式。