Skip to main content

Window management

Avalonia provides a flexible windowing system for creating single-window and multi-window desktop applications. This page covers common window management patterns.

Creating windows

Windows are typically defined in XAML with a code-behind class:

SecondWindow.axaml
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyApp.SecondWindow"
Title="Second Window"
Width="400" Height="300">
<TextBlock Text="Hello from the second window" />
</Window>
SecondWindow.axaml.cs
public partial class SecondWindow : Window
{
public SecondWindow()
{
InitializeComponent();
}
}

Opening a window

var window = new SecondWindow();
window.Show(); // Non-modal: both windows remain interactive

Opening a modal dialog

var dialog = new SecondWindow();
var result = await dialog.ShowDialog<string>(parentWindow);
// Execution resumes here after the dialog closes

The parent window is disabled while the dialog is open. Pass the owner window as the parameter to ShowDialog.

Closing with a result

In the dialog, set the result by calling Close with a value:

// Inside the dialog
Close("user clicked OK");

The value is returned from the ShowDialog<T> call in the parent.

Window properties

PropertyDescription
TitleThe text displayed in the window title bar.
Width, HeightInitial size.
MinWidth, MinHeightMinimum allowed size.
MaxWidth, MaxHeightMaximum allowed size.
WindowStartupLocationWhere the window appears: Manual, CenterScreen, CenterOwner.
PositionThe window position in screen coordinates (when WindowStartupLocation is Manual).
CanResizeWhether the user can resize the window.
CanMinimizeWhether the minimize button is enabled. Defaults to true.
CanMaximizeWhether the maximize button is enabled. Defaults to true. Automatically false when CanResize is false.
IsDialogRead-only. true when the window was opened with ShowDialog, false when opened with Show.
ShowInTaskbarWhether the window appears in the OS taskbar.
TopmostWhether the window stays on top of other windows.
WindowStateCurrent state: Normal, Minimized, Maximized, FullScreen.
SystemDecorationsTitle bar and border style: Full, BorderOnly, None.
ExtendClientAreaToDecorationsHintExtends the client area into the title bar area for custom chrome. Uses WindowDrawnDecorations for application-drawn decorations.
IconThe window icon displayed in the title bar and taskbar.
TransparencyLevelHintEnables window transparency: None, Transparent, AcrylicBlur, Mica.
ClosingBehaviorControls how child windows behave when the owner closes: OwnerAndChildWindows (default, children close first and can cancel) or OwnerWindowOnly (only the owner's Closing event is checked).

Window sizing

Sizing to content

Set SizeToContent to let the window size itself based on its content:

<Window SizeToContent="WidthAndHeight">
<StackPanel Margin="20">
<TextBlock Text="The window will size to fit this content." />
<Button Content="OK" HorizontalAlignment="Right" Margin="0,10,0,0" />
</StackPanel>
</Window>
ValueBehavior
ManualWindow uses Width and Height explicitly (default).
WidthWidth sizes to content, height is explicit.
HeightHeight sizes to content, width is explicit.
WidthAndHeightBoth dimensions size to content.

Saving and restoring window position

protected override void OnOpened(EventArgs e)
{
base.OnOpened(e);

// Restore saved position
if (Settings.WindowLeft >= 0 && Settings.WindowTop >= 0)
{
Position = new PixelPoint(Settings.WindowLeft, Settings.WindowTop);
Width = Settings.WindowWidth;
Height = Settings.WindowHeight;
}
}

protected override void OnClosing(WindowClosingEventArgs e)
{
base.OnClosing(e);

// Save position
Settings.WindowLeft = Position.X;
Settings.WindowTop = Position.Y;
Settings.WindowWidth = Width;
Settings.WindowHeight = Height;
}

Multi-window patterns

Tracking open windows

public static class WindowManager
{
private static readonly List<Window> _openWindows = new();

public static IReadOnlyList<Window> OpenWindows => _openWindows;

public static void Register(Window window)
{
_openWindows.Add(window);
window.Closed += (_, _) => _openWindows.Remove(window);
}

public static void CloseAll()
{
foreach (var window in _openWindows.ToList())
window.Close();
}
}

Finding the parent window from a control

var topLevel = TopLevel.GetTopLevel(myControl);
if (topLevel is Window window)
{
// Use window
}

Or using the extension method:

var window = myControl.FindAncestorOfType<Window>();

Preventing window close

Handle the Closing event to intercept the close action. Set e.Cancel = true to prevent closing:

protected override void OnClosing(WindowClosingEventArgs e)
{
base.OnClosing(e);

if (HasUnsavedChanges)
{
e.Cancel = true;
// Show a save confirmation dialog instead
_ = ShowSavePromptAsync();
}
}

Custom title bar

To create a custom title bar, extend the client area into the decorations and use WindowDecorations.ElementRole to mark a region as the title bar:

<Window ExtendClientAreaToDecorationsHint="True"
SystemDecorations="None">
<Grid RowDefinitions="32,*">
<!-- Custom title bar -->
<Border Grid.Row="0" Background="#2D2D2D"
WindowDecorations.ElementRole="TitleBar">
<TextBlock Text="My App" Foreground="White"
VerticalAlignment="Center" Margin="12,0" />
</Border>
<!-- Content -->
<Border Grid.Row="1">
<TextBlock Text="Window content" />
</Border>
</Grid>
</Window>

Elements marked with WindowDecorations.ElementRole="TitleBar" support native window dragging and double-click-to-maximize. Interactive controls placed inside a title bar region (buttons, text boxes) receive input normally without triggering drag behavior.

For more details on the ElementRole values, see the custom title bar how-to.

Window events

EventWhen it fires
OpenedThe window has been shown for the first time.
ClosingThe window is about to close. Can be cancelled.
ClosedThe window has closed.
ActivatedThe window received focus.
DeactivatedThe window lost focus.
PositionChangedThe window was moved.
ResizedThe window was resized.

Working with screens

The Screens API provides information about connected monitors. Access it from any TopLevel:

var screens = TopLevel.GetTopLevel(this)?.Screens;

Querying screens

// All connected screens
var allScreens = screens.All;

// Primary monitor
var primary = screens.Primary;

// Screen containing a specific window
var currentScreen = screens.ScreenFromWindow(this);

// Screen at a point
var screenAtPoint = screens.ScreenFromPoint(new PixelPoint(500, 300));

Screen properties

Each Screen object exposes:

PropertyTypeDescription
BoundsPixelRectFull screen bounds in pixels.
WorkingAreaPixelRectUsable area excluding taskbars and docks.
ScalingdoubleDPI scaling factor (e.g., 1.0 for 96 DPI, 1.5 for 144 DPI).
IsPrimaryboolWhether this is the primary display.
DisplayNamestring?The OS-reported display name.
CurrentOrientationScreenOrientationThe screen orientation (Landscape, Portrait, and similar).

Responding to screen changes

Subscribe to the Changed event to detect when monitors are added, removed, or reconfigured:

screens.Changed += (sender, args) =>
{
// Re-evaluate window placement or layout
var count = screens.All.Count;
};

Platform differences

FeatureWindowsmacOSLinux
TopmostSupportedSupportedSupported
TransparencyLevelHintAll levelsTransparent onlyDepends on compositor
SystemDecorations.NoneSupportedSupportedSupported
ExtendClientAreaToDecorationsHintSupportedSupportedLimited support
Modal dialogsBlocks parent windowSheet-style on macOSBlocks parent window

See also