WPFでモーダルダイアログを作成する方法


133

WPFで最初のアプリケーションを作成していて、ユーザーにモーダルダイアログウィンドウでデータを入力してもらいたいと思っています。どうやら、これはWPFで行うのは簡単ではありません。親ウィンドウが完全に有効なままであり、新しい子ウィンドウを作成したメソッドは停止せず、子ウィンドウがClose()を呼び出すまで待機しません。代わりに、それは単に前進し続けます。これは私が望むものではありません。

どうすれば子ウィンドウを開いて、親ウィンドウが実行を続ける前に子ウィンドウが閉じるのを親ウィンドウに待機させることができますか?


私の答えをここに共有しください。誰かがGoogleからここをさまようのに役立つかもしれません。
Shahin Dohan

回答:



43

これらの答えの多くは単純化されており、誰かがWPFを始めたとしても、「使用する.ShowDialog()!」ただし、これは、.Show()基になるウィンドウの使用をブロックし、モーダルウィンドウが閉じられるまでコードが続行されないようにするために使用するメソッド(ではない)です。

まず、2つのWPFウィンドウが必要です。(一方が他方を呼び出します。)

最初のウィンドウから、MainWindow.xamlと呼ばれていたとしましょう。そのコードビハインドでは、次のようになります。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
}

次に、ボタンをXAMLに追加します。

<Button Name="btnOpenModal" Click="btnOpenModal_Click" Content="Open Modal" />

Clickルーチンを右クリックして、[定義に移動]を選択します。MainWindow.xaml.csに作成されます。

private void btnOpenModal_Click(object sender, RoutedEventArgs e)
{
}

その関数内で、ページクラスを使用して他のページを指定する必要があります。他のページに「ModalWindow」という名前を付けたとします。これにより、そのページクラスがインスタンス化(呼び出し)されます。

private void btnOpenModal_Click(object sender, RoutedEventArgs e)
{
    ModalWindow modalWindow = new ModalWindow();
    modalWindow.ShowDialog();
}

モーダルダイアログで設定する必要がある値があるとします。ModalWindowXAML でテキストボックスとボタンを作成します。

<StackPanel Orientation="Horizontal">
    <TextBox Name="txtSomeBox" />
    <Button Name="btnSaveData" Click="btnSaveData_Click" Content="Save" /> 
</StackPanel>

次に、イベントハンドラー(別のClickイベント)を再度作成し、それを使用してテキストボックスの値をpublic static変数に保存し、ModalWindowを呼び出しますthis.Close()

public partial class ModalWindow : Window
{
    public static string myValue = String.Empty;        
    public ModalWindow()
    {
        InitializeComponent();
    }

    private void btnSaveData_Click(object sender, RoutedEventArgs e)
    {
        myValue = txtSomeBox.Text;
        this.Close();
    }
}

次に、.ShowDialog()ステートメントの後で、その値を取得して使用できます。

private void btnOpenModal_Click(object sender, RoutedEventArgs e)
{
    ModalWindow modalWindow = new ModalWindow();
    modalWindow.ShowDialog();

    string valueFromModalTextBox = ModalWindow.myValue;
}

29

Window.Show Windowはウィンドウを表示し、実行を続行します-これは非ブロッキング呼び出しです。

Window.ShowDialogは呼び出しスレッド(kinda [1])をブロックし、ダイアログを表示します。また、親/所有ウィンドウとの相互作用もブロックします。(何らかの理由で)ダイアログが閉じられると、ShowDialogは呼び出し元に戻り、DialogResultにアクセスできるようになります(必要な場合)。

[1]ディスパッチャーフレームをWPFディパッチャーにプッシュすることにより、ディスパッチャーポンピングを維持します。これにより、メッセージポンプは引き続きポンピングします。


これについて詳しく説明してください。テストプロセスを実行しているが、警告メッセージがモーダルダイアログとしてポップアップする可能性があるが、実行をブロックしたくないという同様の問題を調べています。
Firoso、2009年

2

WindowオブジェクトmyWindowを指定すると、myWindow.Show()はモードレスで開き、myWindow.ShowDialog()はモーダルで開きます。しかし、私が覚えていることから、後者でさえ妨げません。


6
ブロックすると思います。myWindow.Show()の後のコードは、myWindowがClose()を呼び出すまで実行されません。
Alex Baranosky、2009年

あなたと@AlexBaranoskyの両方が正しい:ShowDialogモーダルが閉じられるまで返らないため、現在実行中のディスパッチャー操作がブロックされます。しかし、ShowDialogそれ自体がを効果的に呼び出すDispatcher.Run()ため、ディスパッチャーは操作の実行を継続し、事実上、UIの応答性を維持します。
マットトーマス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.