6

フォームがあります。

その形式では、実行時間の長いロジックを実行するため、新しいスレッドでクラスのインスタンスを作成します。このフォームにより、ユーザーはこのロジック/スレッドをキャンセルすることもできます。

入力が必要な場合、そのクラスは新しいフォームを開きます。

新しいフォームが他のフォームの後ろに表示されることがあります。

クラスにプロパティを設定します。

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;
    } 
}
4

2 に答える 2

1

参照を取得するタスクをブロックでラップしているため、更新されたメソッド(GetParentForm)は機能しません。代わりに、このようなブロックで呼び出しをラップしてみることができますが、それでもクロススレッドエラーが発生すると思います。ParentFormInvokeRequiredShowDialog

最も簡単な修正は、2番目のフォームを作成して表示するコードをクラスからに移動することParentFormです。したがって、これの代わりに:

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

あなたはこれをするでしょう:

ParentForm.showMyNewForm();

そしてParentFormあなたはこれを持っているでしょう:

public void showMyNewForm()
{
    MyForm form = new MyForm();
    form.ShowDialog(this);
}

MyForm他のスレッドのクラスへの参照が必要な場合は、パラメーターを追加するだけで、そのクラスへshowMyNewForm()の参照を渡すことができます。

ここで実行しようとしていること(異なるスレッドで作成された関連する接続されたフォームを作成して表示すること)は、.NETでのフォームの使用方法の粒度に実際に反しています。

于 2012-06-19T10:53:24.670 に答える
0

フォームに非同期メソッドを追加できます。このように言いましょう:

public class MyForm : Form
{
    public void ShowModalAsync()
    {
        this.Invoke(new Action(()=> {
              ShowDilaog(..);
        }));  
    }
}

次のように使用します。

MyForm form = new MyForm();
form.ShowModalAsync(...);

あなたのために働くはずです。

ちなみに、問題がウィンドウが他のウィンドウの後ろに表示されるという事実だけである場合は、 Form.TopMostプロパティを使用して設定してみてくださいtrue。はい、それを他のフォームの前に持ってくることを念頭に置いてください。しかし、必ずしも他の最上位のフォームの前に持ってくる必要はありません。

于 2012-06-19T09:33:55.980 に答える