我有一个表格。

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

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

新表格有时会出现在其他表格的后面。

我在类(class)上设置了一个属性:

public Form ParentForm{get;set;}

我现在可以做:
MyForm form = new MyForm();
form.ShowDialog(ParentForm);

但是我在调​​用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;
    }
}

最佳答案

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

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

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

您可以这样做:
ParentForm.showMyNewForm();

而在ParentForm中,您将拥有以下内容:
public void showMyNewForm()
{
    MyForm form = new MyForm();
    form.ShowDialog(this);
}

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

您在此处尝试做的事情(创建和显示在不同线程上创建的相关的,相互连接的表单)确实与在.NET中使用表单的方式背道而驰。

关于c# - 将父窗体传递给从类实例调用的ShowDialog,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11098151/

10-09 09:29