Friday, September 22, 2017

Making a Modal Dialog with C# and WPF

Copyright © 2017, Steven E. Houchin. All rights reserved.

For a unit test program I'm developing to validate a new library API, I created a window to show some attributes of an object. I wanted that window to display as follows:

  • normal modal dialog
  • centered on parent window
  • not shown in taskbar
  • can be resized
  • can be minimized

I'm using .NET Framework 4, C# and WPF on a Windows 10 system.

Here are some observations about how to properly set up a dialog as I describe above.

First, to show as a modal dialog, I call the Window class's ShowDialog method to open and show the dialog from the parent Window class:


    // Create the Detail View Controller object
    IDetailViewControl view_controller =
            app.MakeDetailViewController();

    // Create the Detail View Object, passing in this
    // Window class as a parent
    MyDetailView detail =
            new MyDetailView(myDataObject, view_controller, this);
                
    // Show the Detail dialog
    detail.ShowDialog();

Second, to center the dialog on its parent window, the MyDetailView dialog class's constructor sets its Owner property to the Window object passed by the caller:


    public partial class MyDetailView : Window
    {
        public MyDetailView (MyData dataObject,
                             IDetailViewControl controller,
                             Window owner)
        {
            this.Owner = owner;   // set parent window as owner
            InitializeComponent();

            // other constructor initialization
        }
    }



Note that, in the above code, the parent Window code could have set itself as Owner using the 'detail' object before calling ShowDialog, but I chose to have the dialog take care of that. Finally, to complete a centered dialog when open, the dialog Window's XAML properties must specify:

    WindowStartupLocation="CenterOwner"

Third, I set the dialog Window's XAML property to not show in the taskbar:

    ShowInTaskbar="False"

Set to False, it means this dialog will not show in the taskbar, but Restoring the parent window from the taskbar brings the MyDetailView dialog to the top with it.

Lastly, I set the dialog Window's XAML property so it can be resized and minimized:

    ResizeMode="CanResize"

The ResizeMode setting can instead be set to CanMinimize if resizing isn't desired. The CanResize value implies CanMinimize, since minimizing and maximizing is assumed to be part of any resize operation.

So, with the WPF Window implemented this way, it acts like a classic modal dialog we're all accustomed to.