0

フォームAから始めます。
フォームAはフォームBを。で呼び出します.Show()

したがって、フォームAとフォームBの両方にアクセスできます。

ShowDialog()ここで、フォームCが開いているときにフォームBにアクセスできないようにするため、フォームCをで呼び出すフォームBは作成しません。

問題は次のとおりです。フォームAにアクセスできません。

このシナリオでは、フォームAとフォームCの両方にアクセスできるが、フォームBにはアクセスできないようにするにはどうすればよいですか?

4

2 に答える 2

3

これは完全に仕様によるものであり、ダイアログはアプリケーションのすべてのウィンドウを無効にします。この回答で概説されているように、それには正当な理由があります。

簡単に言うと、劇的な失敗のシナリオでは、ユーザーがフォームAのコマンドを使用して、無効にされていないフォームBの別のインスタンスを作成できます。これにより、Cを再度表示できるようになり、2つのダイアログが表示されます。

あなたは、これがあなたの場合には決して起こり得ないことをスパッタするかもしれません。それは大丈夫ですが、ShowDialog()が行うことを元に戻す必要があります。体操が必要な場合は、EnableWindow()を呼び出して、フォームAインスタンスを再度有効にする必要があります。ただし、ShowDialog()の呼び出し後、終了する前に行う必要があります。UIスレッドでControl.BeginInvoke()を使用して実行できること。トリコラマは次のようになります。

    private void ShowDialogButton_Click(object sender, EventArgs e) {
        using (var dlg = new Form3()) {
            // Find the main form instance
            var main = Application.OpenForms.OfType<Form1>().Single();
            this.BeginInvoke(new Action(() => {
                EnableWindow(main.Handle, true);
            }));
            if (dlg.ShowDialog(this) == DialogResult.OK) {
                // etc..
            }
        }
    }

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern bool EnableWindow(IntPtr handle, bool enable);

また、EnableWindow()呼び出しをダイアログのShownイベントハンドラーに配置することもできます。これにより、BeginInvokeトリックを使用する必要がなくなります。ただし、この方法はより普遍的であり、ダイアログは一般に、アプリで実行されている他のウィンドウを知ることを目的としてはなりません。このコードでのForm1の使用は、現状のままでは十分に醜いです。

于 2012-11-26T12:40:23.857 に答える
0

モーダルウィンドウは、ユーザーがアプリケーションの他の部分に戻ることを許可する前に、ユーザーが入力して閉じる必要があるようなものです。そのため、ユーザーが複数のウィンドウを操作できるようにする場合は、これらを使用できません。

EnabledウィンドウCを表示する前にウィンドウBを無効(に設定)しfalse、ウィンドウCが閉じられたら再び有効にすることで、この状況を手動で処理する必要があります。

于 2012-11-26T12:07:09.800 に答える