How to: Create and Manage Dialog Boxes

When you create a modal dialog box inside Visual Studio, you must make sure that the parent window of the dialog box is disabled while the dialog box is displayed, then re-enable the parent window after the dialog box is closed. If you do not do so, you may receive the error: "Microsoft Visual Studio cannot shut down because a modal dialog is active. Close the active dialog and try again."

There are two ways of doing this. The recommended way, if you have a WPF dialog box, is to derive it from DialogWindow, and then call ShowModal to display the dialog box. If you do this, you do not need to manage the modal state of the parent window.

If your dialog box is not WPF, or for some other reason you cannot derive your dialog box class from DialogWindow, then you must get the parent of the dialog box by calling GetDialogOwnerHwnd and manage the modal state yourself, by calling the EnableModeless method with a parameter of 0 (false) before displaying the dialog box and calling the method again with a parameter of 1 (true) after closing the dialog box.

To create a dialog box derived from DialogWindow

  1. Create a Visual Studio Package solution named OpenDialogTest that adds a menu command named OpenDialog. For more information about how to do this, see Walkthrough: Creating a Menu Command By Using the Visual Studio Package Template.

  2. To use the DialogWindow class, you must add references to the following assemblies:

    • PresentationCore

    • PresentationFramework

    • WindowsBase

    • System.Xaml

  3. Add the following using declaration (Imports in Visual Basic) to the OpenDialogTestPackage file:

    Imports Microsoft.VisualStudio.PlatformUI
    
    using Microsoft.VisualStudio.PlatformUI;
    
  4. Declare a class named TestDialogWindow that derives from DialogWindow:

    Class TestDialogWindow
        Inherits DialogWindow
    
    class TestDialogWindow : DialogWindow
    
  5. In the OpenDialogTestPackage.MenuItemCallback method, replace the existing code with the following:

    Private Sub MenuItemCallback(ByVal sender As Object, ByVal e As EventArgs)
        Dim testDialog As TestDialogWindow = New TestDialogWindow()
        testDialog.ShowModal()
    
    End Sub
    
    private void MenuItemCallback(object sender, EventArgs e)
    {
        TestDialogWindow testDialog = new TestDialogWindow();
        testDialog.ShowModal();
    }
    
  6. Build and run the application. On the Tools menu you should see a command named OpenDialog. When you click this command, you should see the dialog window.

To create and manage a dialog box not derived from DialogWindow

  1. For this procedure, you can use the OpenDialogTest solution you created in the previous procedure, with the same assembly references.

  2. Add the following using declarations (Imports in Visual Basic:

    Imports System.Windows
    Imports Microsoft.Internal.VisualStudio.PlatformUI
    
    using System.Windows;
    using Microsoft.Internal.VisualStudio.PlatformUI;
    
  3. Create a class named TestDialogWindow2 that derives from Window:

    Class TestDialogWindow2
        Inherits Window
    
    class TestDialogWindow2 : Window
    
  4. Add a private reference to IVsUIShell:

    Private m_shell As IVsUIShell
    
    private IVsUIShell m_shell;
    
  5. Add a constructor that sets the reference to IVsUIShell:

    Public Sub New(ByVal shell As IVsUIShell)
        m_shell = shell
    End Sub
    
    public TestDialogWindow2(IVsUIShell shell)
    {
        m_shell = shell;
    }
    
  6. In the OpenDialogTestPackage.MenuItemCallback method, replace the existing code with the following:

    Private Sub MenuItemCallback(ByVal sender As Object, ByVal e As EventArgs)
        Dim uiShell As IVsUIShell = TryCast(GetService(GetType(SVsUIShell)), IVsUIShell)
        Dim testDialog2 As TestDialogWindow2 = New TestDialogWindow2(uiShell)
        Dim hwnd As IntPtr = Nothing
    
        uiShell.GetDialogOwnerHwnd(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)
        End Try
    End Sub
    
    private void MenuItemCallback(object sender, EventArgs e)
    {
        IVsUIShell uiShell = (IVsUIShell)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. Build and run the application. On the Tools menu you should see a command named OpenDialog. When you click this command, you should see the dialog window.