如何在第一个表单的同一线程上打开第二个表单?

时间:2019-06-25 08:40:35

标签: c# .net winforms

我有一个带有2个表单的WinForms客户端。第一种形式调用一个单独的类,该类使用'SignalR'来接收来自WebApi的通知。该类中特定消息的集线器代理的设置是:

onResult = myProxy.On<int>("Result", (id) =>
{
    Result?.Invoke(this, new ResultEventArgs(id));
});

在第一种形式中,我订阅了Result事件,然后我拥有:

private void OnResult(object sender, ResultEventArgs e)
{
   using (var form = new SecondForm(e))
   {
       var dialogResult = form.ShowDialog(this);
       if (dialogResult == DialogResult.Cancel)
           return;
   }
}

我在CrossThreadException上得到一个var dialogResult = form.ShowDialog(this);,第一个表单(this)在UI线程上打开。第二种形式是在SignalR类使用的同一线程中打开的。

我确实需要使用ShowDialog(this)打开第二个表单,因为它需要成为应用程序中最顶层的表单。

是否有解决此问题的方法?是否可以在UI线程中打开第二个表单?

更新:

一种可行的解决方法:

form.TopMost = true;                   
form.StartPosition = FormStartPosition.CenterScreen;

唯一的缺点是该表单是桌面上最顶层的表单,而不仅是在应用程序中。

1 个答案:

答案 0 :(得分:2)

您不能在单个UI线程以外的任何线程上创建,更改或访问任何UI控件。您必须在现有控件上调用.Invoke(...),以将来自另一个线程的调用编组回UI。

尝试一下:

private void OnResult(object sender, ResultEventArgs e)
{
    Action x = () =>
    {
        using (var form = new SecondForm(e))
        {
            var dialogResult = form.ShowDialog(this);
            if (dialogResult == DialogResult.Cancel)
                return;
        }
    };

    this.Invoke(x);
}