我遇到一个问题与Windows形式应用程序。

形式必须显示从另外一个线程。因此,在形成类,我有下列代码:

private delegate void DisplayDialogCallback();

public void DisplayDialog()
{
    if (this.InvokeRequired)
    {
        this.Invoke(new DisplayDialogCallback(DisplayDialog));
    }
    else
    {
        this.ShowDialog();
    }
}

现在,每次我经营这个, InvalidOperationException 是扔在线 this.ShowDialog();:

"跨线操作无效:控制'SampleForm'访问时从一个线程比其他的线创建它。"

什么是错的这段代码?是不是一个有效方法,使跨线的电话?是不是有什么特别的 ShowDialog()?

有帮助吗?

解决方案

试试这个:

private delegate void DisplayDialogCallback();

public void DisplayDialog()
{
    if (this.InvokeRequired)
    {
        this.Invoke(new DisplayDialogCallback(DisplayDialog));
    }
    else
    {
        if (this.Handle != (IntPtr)0) // you can also use: this.IsHandleCreated
        {
            this.ShowDialog();

            if (this.CanFocus)
            {
                this.Focus();
            }
        }
        else
        {
            // Handle the error
        }
    }
}

请注意, InvokeRequired 返回

真的,如果控制的处理是 上创建一个不同的线比 叫线(指示您 必须打电话来控制通过 调用的方法);否则,假。

因此,如果控制尚未建立,返回值将 false!

其他提示

你可能执行这些代码前的形式已经显示。
因此, InvokeRequired 正在返回 false.

我相信这里发生了什么的是,这个代码是正在运行之前 Form 是有史以来所示。

当一个 Form 创建中。净它不会立即获得亲和对于特定的线。只有当某些行动的执行等,表示它或夺取的处理不得力。在此之前发生的很难 InvokeRequired 能够正常工作。

在这种特定情况下没有亲和力的建立和没有父母控制存在这样 InvokeRequired 返回虚假的因为它不能确定原始的线。

的方式来解决这个问题是建立亲对你的控制时,它的创建UI上的螺纹。最好的方式做到这仅仅是要求控制对于它处理的财产。

var notUsed = control.Handle;

你可能会获得这个代码前的形式已经显示出,因此窗口处理尚未建立。

你可以添加这段代码之前你代码和所有的应该是好的:

if (! this.IsHandleCreated)
   this.CreateHandle();

编辑: 还有另外一个问题与你的代码。一旦形式显示,你无法叫ShowDialog()。你会得到一个无效运行异常。你可能希望修改这种方法为其他人已经提出了建议。

你可能会得到更好的服务,叫ShowDialog()直接从呼叫类,并有另一个方法BringToFront()或类似的东西...

你总是可以尝试试对一个不同的控制。

例如,你可以进入应用程序。形式收藏

public Control GetControlToInvokeAgainst()
{
    if(Application.Forms.Count > 0)
    {
        return Application.Forms[0];
    }
    return null;
}

然后在你DisplayDialog()方法,调GetControlToInvokeAgainst()并测试空前努力来执行一个invokerequired的呼吁。

最有可能处理的控制并不是创建然而,在这种情况下 Control.InvokeRequired 返回 false.

检查 Control.IsHandleCreated 酒店看到的,如果是这种情况。

我还认为SLaks是正确的。从msdn(http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invokerequired.aspx):

如果没有适当处理,可以发现,InvokeRequired方法返回错误的。

如果它能够在你的种情况下,我将试图结合建立,并表示控制在一个单一的方法,即:

public DisplayDialog static Show()
{
  var result = new DisplayDialog; //possibly cache instance of the dialog if needed, but this could be tricky
  result.ShowDialog(); 
  return result;
}

你可以打电话显示从一个不同的纹

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top