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

标签 c# .net winforms multithreading

我有一个表格。

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

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

新表格有时会出现在另一个表格后面。

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

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 调用包装在这样的 block 中,但我认为您仍然会遇到跨线程错误。

最简单的解决方法是将创建和显示第二个窗体的代码从类中移出并移到 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/

相关文章:

c# - C# 中 32 位 * 32 位数据的问题

使用 Ubuntu 的 C# Windows 应用程序

c# - 位/字节转换

.net - 在 TPL 中复制队列

c# - .NET Winforms 应用程序在启动时死掉

c# - 制作透明标签背景?

c# - 如何从外部程序集访问内部类?

C# 创建具有自定义属性的基本表单

mysql - 除了初始成本之外,使用 MySQL 而不是 SQL Server 和 .net 有什么其他好处吗?

c# - 如何使用列表框将文本文件字符串发送到文本框?