モーダル ダイアログ ボックスの作成と管理

Visual Studio 内にモーダル ダイアログ ボックスを作成する場合は、そのダイアログ ボックスが表示されている間はダイアログ ボックスの親ウィンドウが必ず無効になるようにし、そのダイアログ ボックスが閉じた後で親ウィンドウを再び有効にする必要があります。 そうしないと、Microsoft Visual Studio cannot shut down because a modal dialog is active. Close the active dialog and try again. (モーダル ダイアログがアクティブになっているため、Microsoft Visual Studio をシャットダウンできません。アクティブなダイアログを閉じてから、もう一度お試しください。) というエラーが表示される可能性があります。

これを行うには 2 つの方法があります。 推奨される方法 (WPF ダイアログ ボックスがある場合) は、DialogWindow からそれを派生させた後、ShowModal を呼び出してそのダイアログ ボックスを表示することです。 これを行うと、親ウィンドウのモーダル状態を管理する必要がなくなります。

お使いのダイアログ ボックスが WPF でない場合、または他の何らかの理由で DialogWindow からダイアログ ボックス クラスを派生できない場合は、ダイアログ ボックスの親を取得する必要があります。そのためには、GetDialogOwnerHwnd を呼び出してモーダル状態を自身で管理するか、ダイアログ ボックスの表示前にパラメーター 0 (false) を指定して EnableModeless メソッドを呼び出し、ダイアログ ボックスのクローズ後にパラメーター 1 (true) を指定してそのメソッドを呼び出します。

DialogWindow から派生したダイアログ ボックスを作成する

  1. OpenDialogTest という名前の VSIX プロジェクトを作成し、OpenDialog という名前のメニュー コマンドを追加します。 この方法の詳細については、「メニュー コマンドを使用して拡張機能を作成する」をご覧ください。

  2. DialogWindow クラスを使用するために、以下のアセンブリへの参照を追加する必要があります ([参照の追加] ダイアログ ボックスの [フレームワーク] タブを使用)。

    • PresentationCore

    • PresentationFramework

    • WindowsBase

    • System.Xaml

  3. OpenDialog.cs に、次の using ステートメントを追加します。

    using Microsoft.VisualStudio.PlatformUI;
    
  4. DialogWindow から派生する TestDialogWindow という名前のクラスを宣言します。

    class TestDialogWindow : DialogWindow
    {. . .}
    
  5. ダイアログ ボックスを最小化および最大化できるようにするために、HasMaximizeButtonHasMinimizeButton を true に設定します。

    internal TestDialogWindow()
    {
        this.HasMaximizeButton = true;
        this.HasMinimizeButton = true;
    }
    
  6. OpenDialog.ShowMessageBox メソッド内で、既存のコードを次のように置き換えます。

    TestDialogWindow testDialog = new TestDialogWindow();
    testDialog.ShowModal();
    
  7. アプリケーションをビルドして実行します。 Visual Studio の実験用インスタンスが表示されます。 実験用インスタンスの [ツール] メニューに、Invoke OpenDialog という名前のコマンドが表示されます。 このコマンドをクリックすると、ダイアログ ウィンドウが表示されます。 ウィンドウを最小化および最大化できるようになります。

DialogWindow から派生していないダイアログ ボックスを作成して管理する

  1. この手順では、前の手順で作成した OpenDialogTest ソリューションと、同じアセンブリ参照を使用できます。

  2. 次の using 宣言を追加します。

    using System.Windows;
    using Microsoft.Internal.VisualStudio.PlatformUI;
    
  3. Window から派生する TestDialogWindow2 という名前のクラスを作成します。

    class TestDialogWindow2 : Window
    {. . .}
    
  4. IVsUIShell へのプライベート参照を追加します。

    private IVsUIShell shell;
    
  5. IVsUIShell への参照を設定するコンストラクターを追加します。

    public TestDialogWindow2(IVsUIShell uiShell)
    {
        shell = uiShell;
    }
    
  6. OpenDialog.ShowMessageBox メソッド内で、既存のコードを次のように置き換えます。

    IVsUIShell uiShell = (IVsUIShell)ServiceProvider.GetService(typeof(SVsUIShell));
    
    TestDialogWindow2 testDialog2 = new TestDialogWindow2(uiShell);
    //get the owner of this dialog
    IntPtr hwnd;
    uiShell.GetDialogOwnerHwnd(out hwnd);
    testDialog2.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
    uiShell.EnableModeless(0);
    try
    {
        WindowHelper.ShowModal(testDialog2, hwnd);
    }
    finally
    {
        // This will take place after the window is closed.
        uiShell.EnableModeless(1);
    }
    
  7. アプリケーションをビルドして実行します。 [ツール] メニューに、Invoke OpenDialog という名前のコマンドが表示されます。 このコマンドをクリックすると、ダイアログ ウィンドウが表示されます。