MetroWindow

MetroWindow replaces WPF's Window. Using it is what gives an application the MahApps title bar, and it is the host for flyouts, dialogs and the title-bar commands. If you are starting out, read the Quick Start first.

It has around fifty properties. They are grouped here by what they do rather than listed alphabetically.

The title bar

The defaults, a centred title, normal casing, and no title bar

Property Type Default
ShowTitleBar bool True
TitleBarHeight int 30
TitleAlignment HorizontalAlignment Stretch
TitleCharacterCasing CharacterCasing Upper why titles shout by default
TitleForeground Brush
TitleTemplate DataTemplate null replace the title's presentation entirely
WindowTitleBrush Brush Transparent the bar's background
NonActiveWindowTitleBrush Brush Gray the same while the window is inactive
UseNoneWindowStyle bool False no title bar and no border at all

TitleCharacterCasing="Normal" is the one most people reach for first — the third panel above.

ShowTitleBar="False" removes the bar but not the window buttons: the fourth panel above still has minimise, maximise and close floating over the content. That is WindowButtonCommandsOverlayBehavior, which defaults to Always and so includes the hidden-title-bar case. Set it to Never if you want them gone with the bar.

WindowTitleBrush being Transparent by default is worth knowing: the accent colour you see comes from the theme, not from this property, so setting it is how you get a title bar that ignores the theme.

Borders, glow and shadow

A one-pixel border, no border, and a taller title bar

A normal border is BorderBrush plus BorderThickness, inherited from Window:

<mah:MetroWindow BorderBrush="{DynamicResource MahApps.Brushes.Accent}"
                 BorderThickness="1" />

GlowBrush instead draws a soft glow around the frame:

<mah:MetroWindow GlowBrush="{DynamicResource MahApps.Brushes.Accent}" />

A window with a glow

The glow is painted by separate windows around the frame, not by the window's own visual tree. A BorderThickness="0" window with no GlowBrush therefore has no edge at all — the middle panel of the first figure.

For a drop shadow and no border, set BorderThickness="0" with a dark GlowBrush:

<mah:MetroWindow BorderThickness="0"
                 GlowBrush="Black"
                 ResizeMode="CanResizeWithGrip"
                 WindowTransitionsEnabled="False" />
Property Type Default
GlowBrush Brush null
NonActiveGlowBrush Brush the glow while inactive
NonActiveBorderBrush Brush Gray
KeepBorderOnMaximize bool True
ResizeBorderThickness Thickness 6 the invisible grab area for resizing

The window buttons

All three, a disabled close button, and only the close button

There are two pairs of properties, and they do different things:

ShowMinButton, ShowMaxRestoreButton, ShowCloseButton remove the button
IsMinButtonEnabled, IsMaxRestoreButtonEnabled, IsCloseButtonEnabled keep it, greyed out

All six default to True. The middle panel above is a disabled close button — still there, still visibly a button; the right-hand one has the other two removed outright.

WindowButtonCommands is the control itself, should you want to reach it — see WindowButtonCommands, which also has the cancellable ClosingWindow event.

ShowSystemMenu and ShowSystemMenuOnRightClick (both True) control the system menu.

Title-bar commands and the icon

LeftWindowCommands and RightWindowCommands take a WindowCommands each, for your own buttons at either end of the bar. OverrideDefaultWindowCommandsBrush forces a brush onto all of them at once.

Property Type Default
ShowIconOnTitleBar bool True
IconTemplate DataTemplate null
IconScalingMode MultiFrameImageMode ScaleDownLargerFrame see MultiFrameImage
IconBitmapScalingMode BitmapScalingMode
IconEdgeMode EdgeMode
IconOverlayBehavior OverlayBehavior Never whether the icon shows over a flyout

Icon is inherited from Window and takes only an ImageSource (Microsoft docs). For anything else, use IconTemplate — the icon is bound to it, so {Binding} inside the template is the Icon.

<mah:MetroWindow Icon="app.ico" ShowIconOnTitleBar="True">
    <mah:MetroWindow.IconTemplate>
        <DataTemplate>
            <Image Margin="4" RenderOptions.BitmapScalingMode="HighQuality" Source="{Binding}" />
        </DataTemplate>
    </mah:MetroWindow.IconTemplate>
</mah:MetroWindow>

The template does not have to show the Icon at all — put an icon-pack glyph in it and the window has a vector icon:

<mah:MetroWindow.IconTemplate>
    <DataTemplate>
        <iconPacks:PackIconUnicons Width="30" Height="30" Margin="4"
                                   Kind="BatteryBolt"
                                   Foreground="{DynamicResource MahApps.Brushes.IdealForeground}" />
    </DataTemplate>
</mah:MetroWindow.IconTemplate>

Because the icon is drawn by a MultiFrameImage, a multi-resolution .ico picks the frame that suits the title bar rather than being stretched — IconScalingMode is that control's mode.

Clicking the icon

The icon behaves like the one on any other window: a left click opens the system menu, a double click closes the window. ShowSystemMenu and CloseOnIconDoubleClick (both True) turn either of those off.

A right click is left to the template, so an icon of your own can bring a menu of its own:

<mah:MetroWindow.IconTemplate>
    <DataTemplate>
        <Image Margin="4" Source="{Binding}">
            <Image.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Settings" />
                    <MenuItem Header="About" />
                </ContextMenu>
            </Image.ContextMenu>
        </Image>
    </DataTemplate>
</mah:MetroWindow.IconTemplate>

Where the template has none, the right click falls back to the system menu, which is what Windows does on an icon, and ShowSystemMenuOnRightClick turns that off.

In a released version the system menu takes the right click either way, so a menu in the template never gets its turn. Fixed on develop by #4488.

Flyouts and dialogs

Flyouts takes the FlyoutsControl holding the window's flyouts, and FlyoutOverlayBrush paints the dimming behind a modal one.

Property Type Default
MetroDialogOptions MetroDialogSettings defaults for the dialogs shown on this window
ShowDialogsOverTitleBar bool True
OverlayBrush Brush the dialog overlay
OverlayOpacity double 0.7
OverlayFadeIn / OverlayFadeOut Storyboard replace the fade
IsAnyDialogOpen bool, read-only False
IsCloseButtonEnabledWithDialog bool, read-only True whether the close button works while a dialog is up

The four overlay-behaviour properties — LeftWindowCommandsOverlayBehavior, RightWindowCommandsOverlayBehavior, WindowButtonCommandsOverlayBehavior and IconOverlayBehavior — decide what stays visible above an open flyout. They are documented with their defaults on the Flyouts page.

A WindowsFormsHost over a dialog

New on develop with #3849.

A WindowsFormsHost, a WebBrowser, anything built on HwndHost is a window of its own sitting on top of yours. It paints over the WPF content around it whatever the z order says, so a dialog or a flyout drawn over it is cut in half. There is nothing to arrange your way out of, and it is a WPF thing rather than a MahApps one.

The only way to show the dialog whole is for the hosted handle to be gone while it is up, which is what CollapseHwndHosts does:

<mah:MetroWindow x:Class="Sample.MainWindow"
                 xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
                 CollapseHwndHosts="True">
    <DockPanel>
        <TextBlock DockPanel.Dock="Top" Text="a report" />
        <WindowsFormsHost>
            <wf:ReportViewer x:Name="Viewer" />
        </WindowsFormsHost>
    </DockPanel>
</mah:MetroWindow>

Every HwndHost in the window is collapsed for as long as a dialog or a Flyout is open, and gets back the visibility it had once the last of them is gone. A flyout counts as gone when it has finished sliding out, not when it is told to close, so nothing pops up in front of it on the way.

The price is that the hosted control disappears and comes back. It is only hidden, not rebuilt: the window handle stays the same, and so does whatever the control holds, its text and its caret. But it is visibly gone while the dialog is up and it redraws when it returns, which for something like a video player or a browser is an interruption rather than a flicker. That is why this is off by default.

Position, dragging and startup

Property Type Default
SaveWindowPosition bool False restore size and position on next launch
WindowPlacementSettings IWindowPlacementSettings null where that is stored
IgnoreTaskbarOnMaximize bool False maximise over the taskbar
IsWindowDraggable bool True drag the window by its title bar
WindowTransitionsEnabled bool True the content's entrance animation
TryToBeFlickerFree bool False

SaveWindowPosition="True" is a nice convenience and a real support risk. If a monitor is detached between exit and restart, the window can come back off screen with no way for the user to get at it. Provide a reset, or validate the restored placement against the current screens yourself.

Where the placement is stored

Left alone, the placement goes into the application settings, through ApplicationSettingsBase. That store depends on the configuration system, and it does fail: on .NET 9 before 9.0.3 saving throws when the application runs from a network location, and the position is silently lost.

WindowPlacementSettings takes any IWindowPlacementSettings, so the storage is yours to pick. WindowPlacementFileSettings writes a file instead, either one you name or one under the local application data of the current user:

public MainWindow()
{
    this.InitializeComponent();
    this.WindowPlacementSettings = WindowPlacementFileSettings.ForWindow(this);
}

It has no dependency on the configuration system, and it behaves the same on every target framework. Writing your own implementation is a small interface away if you would rather keep the placement in a database or next to the rest of your own settings.

WindowPlacementFileSettings is on develop and ships with the next release. In a released version, write the interface yourself, it is Placement, Reload, Save, Upgrade, UpgradeSettings and Reset.

IsWindowDraggable is what MetroThumbContentControl checks — the title bar is one of those, and dragging it is what moves the window.

WindowCommands and WindowButtonCommands for the title bar's two sets of buttons. Flyouts for the overlay panels and the overlay-behaviour table. MetroNavigationWindow is a MetroWindow with a navigation bar built in.