ChildWindow

ChildWindow is a window that opens inside a MetroWindow. It is a ContentControl with a title bar of its own, and it sits over an overlay in the container the dialogs use, where it can be moved and closed. It brings no buttons and no result type of its own, so the content and what the window hands back are up to you.

ChildWindow is new on develop. In 2.4.11 it is the separate package MahApps.Metro.SimpleChildWindow. The last section says what changes when you move over.

<mah:ChildWindow Title="A question" ChildWindowWidth="360">
    <StackPanel Margin="16">
        <TextBlock Text="What is the answer?" />
        <Button Content="42" Click="OnAnswer" />
    </StackPanel>
</mah:ChildWindow>
var answer = await this.ShowChildWindowAsync<string>(new QuestionChildWindow());

ShowChildWindowAsync is an extension method on the window. It puts the child window into the dialog container, opens it and completes once it is closed and gone again.

Closing it and the result

Close(result) closes the window, and ShowChildWindowAsync<TResult> returns that result. Closed without one, by Escape, by the close button or by a click on the overlay, the task returns the CloseReason instead if TResult can hold it, and the default otherwise. ClosedBy says which of these it was. The Closing event can cancel a close.

Escape closes the window unless CloseByEscape is off. A click on the overlay closes it only with CloseOnOverlay, and IsAutoCloseEnabled closes it on its own after AutoCloseInterval milliseconds.

The overlay and the title bar

ShowChildWindowAsync takes an OverlayFillBehavior. WindowContent, the default, leaves the title bar of the window free, FullWindow covers it as well. IsModal set to false takes the veil away, while the overlay still catches the click that CloseOnOverlay asks for. Its brush is MahApps.Brushes.ChildWindow.Overlay and follows the theme.

AllowMove lets the title bar move the window around, as long as it is not stretched across. ShowTitleBarCloseButton puts a close button into the title bar, and ShowTitleBar set to false leaves the bar out altogether. TitleBarCloseButtonCommand runs when that button is clicked, and its CanExecute can keep the window open. Closing the window any other way does not run it.

From a view model

IDialogCoordinator.ShowChildWindowAsync does the same for a view model that is registered with DialogParticipation.Register, the way the MVVM dialogs do it.

Coming from SimpleChildWindow

Replace the http://metro.mahapps.com/winfx/xaml/simplechildwindow namespace with the controls one, http://metro.mahapps.com/winfx/xaml/controls, and drop the package. The title bar has names of its own now:

SimpleChildWindow MahApps.Metro
ShowCloseButton ShowTitleBarCloseButton
CloseButtonStyle TitleBarCloseButtonStyle
CloseButtonCommand, CloseButtonCommandParameter TitleBarCloseButtonCommand, TitleBarCloseButtonCommandParameter
Icon, IconTemplate TitleBarIcon, TitleBarIconTemplate
TitleForeground TitleBarForeground
PART_Header, PART_HeaderThumb, PART_Icon, PART_CloseButton PART_TitleBar, PART_TitleBarThumb, PART_TitleBarIcon, PART_TitleBarCloseButton

The close command used to run on every close. Now it runs for the close button alone. TitleBarHeight is a double now instead of an int, and ShowChildWindowAsync<TResult> returns Task<TResult?>. Setting CornerRadius from code reaches the window as well, where the package wrote the attached property of Border instead.

MetroWindow hosts it, and its IsAnyDialogOpen is true while a child window is open. The dialogs share the same container, and whichever opens last lies on top. ContentDialog builds on it, with the buttons and the result of the WinUI dialog.