2016-05-20 3 views
-1

ここでは、InvokeRequiredを明確にチェックしていますが、falseが返され、続いてInvalidOperationExceptionがスローされます。私は間違って何をしていますか?Form.Focus InvalidOperationException:クロススレッド操作が有効でない

/// <summary>Position the specified form within the specified bounds, 
/// and focus it, all in a thread-safe manner.</summary> 
private static void FocusForm_Helper(Form form, double top, double height, double left, double width) 
{ 
    if (form?.IsDisposed ?? true) 
     return; 
    if (form.InvokeRequired) 
    { 
     form.Invoke((Action)(() => FocusForm_Helper(form, top, height, left, width))); 
     return; 
    } 
    form.Top = (int)(top + 0.5 * (height /*- form.Height*/)); 
    form.Left = (int)(left + 0.5 * (width /*- form.Width*/)); 
    form.Focus(); 
} 

のSystem.InvalidOperationException:クロススレッド操作ではない有効: コントロール「DataUploadDialog」が作成された スレッド以外のスレッドからアクセス。 のSystem.Windows.FormsでSystem.Windows.Forms.Control.FocusInternal()で System.Windows.Forms.Control.get_CanFocus()でSystem.Windows.Forms.Control.get_Handle()で

。 Control.Focus()は ExcelDNA.CustomRibbon.FocusForm_Helper(フォーム形式、ダブルトップ、ダブル 高さ、ダブル左、ダブル幅)

で私は、メインスレッド上でこのコントロールを作成し、その後、別の上でそれを実行しましたそれ自身のメッセージポンプを持つようにします。私は必要に応じてInvokeRequiredを検出し、適切なスレッドで "Focus"を呼び出すことを期待しているコントロールにフォーカスを呼び出しますが、それは起こっていません。

_launchedDataUploadDialog = new DataUploadDialog(); 
var thread = new Thread(() => 
{ 
    try 
    { 
     System.Windows.Forms.Application.Run(_launchedDataUploadDialog); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("Data upload utility halted unexpectedly.\n\n" + ex); 
     _launchedDataUploadDialog = null; 
    } 
}); 
thread.TrySetApartmentState(ApartmentState.STA); 
thread.Start(); 
FocusForm(_launchedDataUploadDialog); 
+0

それは 'DataUploadDialog'文句、あなたはおそらく別のスレッドでいくつかのコントロールを構築したのですか? –

+0

@ LasseV.Karlsenフォームはメインスレッドで作成されますが、独自のアパートメント状態のスレッドから実行されます。私はそれを示すために質問を更新しました。 – Alain

+0

なぜあなたは自分自身に再帰していますか? – t0mm13b

答えて

-1

この場合の解決策は、Focus()方法は、フォーム自体が、フォームによって表示されるメイン制御に作用しないことです。フォームがApplication.Runによって呼び出されたためにフォームが独自のアパート状態になっている場合、そのInvokeRequiredは関連性がなく、主なコントロールのものです。

だから解決策は次のとおりです。

if (form.Controls[0].InvokeRequired) 
{ 
    form.Controls[0].BeginInvoke((Action)(() => ...)); 
    return; 
} 
form.Focus(); 
関連する問題