Skip to main content

How to: Work with Windows

This guide covers common Window scenarios: sizing, positioning, dialogs, multi-window apps, startup behavior, and system chrome.

Setting Window Size and Position

Fixed size on startup

<Window Width="800" Height="600"
WindowStartupLocation="CenterScreen">

Minimum and maximum size

<Window MinWidth="400" MinHeight="300"
MaxWidth="1920" MaxHeight="1080">

Startup location

ValueDescription
ManualPosition set by Position property.
CenterScreenCentered on the primary screen.
CenterOwnerCentered on the owner window (for dialogs).

Showing a Dialog Window

Use ShowDialog<T> to open a modal dialog and get a result:

var dialog = new SettingsWindow();
var result = await dialog.ShowDialog<bool>(this);
if (result)
{
// User confirmed
}

Return a result by calling Close with a value:

// In the dialog window
private void OnOkClick(object sender, RoutedEventArgs e)
{
Close(true);
}

private void OnCancelClick(object sender, RoutedEventArgs e)
{
Close(false);
}

Getting the Parent Window

From any control, use TopLevel.GetTopLevel:

var topLevel = TopLevel.GetTopLevel(this);
if (topLevel is Window window)
{
await new MyDialog().ShowDialog<bool>(window);
}

Preventing Window Close

Handle the Closing event to intercept close attempts:

protected override void OnClosing(WindowClosingEventArgs e)
{
if (HasUnsavedChanges)
{
e.Cancel = true;
// Show save prompt
}
base.OnClosing(e);
}

Window State (Minimize, Maximize, Restore)

// Programmatically control window state
window.WindowState = WindowState.Maximized;
window.WindowState = WindowState.Minimized;
window.WindowState = WindowState.Normal;
<Button Content="Maximize" Command="{Binding MaximizeCommand}" />
[RelayCommand]
private void Maximize()
{
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
var window = desktop.MainWindow;
window.WindowState = window.WindowState == WindowState.Maximized
? WindowState.Normal
: WindowState.Maximized;
}
}

Disabling Minimize and Maximize Buttons

Use CanMinimize and CanMaximize to control whether the title bar buttons are enabled:

<Window CanMinimize="False" CanMaximize="False">

When CanResize is false, CanMaximize is automatically set to false.

note

Platform behavior varies. On Windows, disabled buttons are hidden. On macOS, they appear greyed out. On Linux, behavior depends on the window manager.

Hiding the Title Bar (Chromeless Window)

Create a borderless window by disabling system decorations:

<Window SystemDecorations="None"
ExtendClientAreaToDecorationsHint="True"
Background="Transparent"
TransparencyLevelHint="AcrylicBlur">

Custom title bar with drag region

Mark an element as a title bar drag region using the WindowDecorations.ElementRole attached property. The operating system handles drag and double-click-to-maximize behavior automatically:

<Grid RowDefinitions="32,*">
<!-- Custom title bar -->
<Border Grid.Row="0" Background="#1E1E2E"
WindowDecorations.ElementRole="TitleBar">
<DockPanel Margin="8,0">
<TextBlock Text="My App" VerticalAlignment="Center" Foreground="White" />
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal"
HorizontalAlignment="Right">
<Button Content="_" Command="{Binding MinimizeCommand}" />
<Button Content="" Command="{Binding MaximizeCommand}" />
<Button Content="" Command="{Binding CloseCommand}" />
</StackPanel>
</DockPanel>
</Border>

<!-- Content -->
<ContentControl Grid.Row="1" Content="{Binding CurrentView}" />
</Grid>

The ElementRole property supports these values:

ValueBehavior
NoneNo special window chrome behavior (default).
TitleBarActs as a draggable title bar region.
ResizeN, ResizeS, ResizeE, ResizeWResize grip for the specified edge.
ResizeNE, ResizeNW, ResizeSE, ResizeSWResize grip for the specified corner.

Interactive controls inside a TitleBar region (such as buttons) continue to receive input normally and do not trigger window dragging.

Multi-Window Application

Open additional windows from the main window:

[RelayCommand]
private void OpenNewWindow()
{
var window = new SecondaryWindow
{
DataContext = new SecondaryViewModel()
};
window.Show();
}

For a non-modal window that stays on top of the owner:

var toolWindow = new ToolWindow();
toolWindow.Show(ownerWindow); // Stays above owner

Saving and Restoring Window Position

protected override void OnOpened(EventArgs e)
{
base.OnOpened(e);
var settings = LoadSettings();
if (settings.WindowWidth > 0)
{
Width = settings.WindowWidth;
Height = settings.WindowHeight;
}
}

protected override void OnClosing(WindowClosingEventArgs e)
{
SaveSettings(new AppSettings
{
WindowWidth = Width,
WindowHeight = Height,
WindowState = WindowState
});
base.OnClosing(e);
}

Window Transparency

<!-- Acrylic blur (platform-dependent) -->
<Window TransparencyLevelHint="AcrylicBlur"
Background="Transparent">
<Panel>
<ExperimentalAcrylicBorder Material="{DynamicResource AcrylicMaterial}" />
<!-- Content on top of acrylic -->
</Panel>
</Window>

Check which transparency levels are supported at runtime:

var supported = this.ActualTransparencyLevel;

Transparent click-through window

To create a transparent overlay window where mouse clicks pass through empty areas to applications underneath, set TransparencyLevelHint="Transparent" and remove the window's Background by setting it to {x:Null}. Interactive controls placed in the window remain clickable.

<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
TransparencyLevelHint="Transparent"
Background="{x:Null}"
SystemDecorations="None"
Topmost="True"
WindowState="Maximized">
<Grid>
<!-- This button is clickable; empty areas pass input through -->
<Button Content="Click Me"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</Window>

The key difference is between Background="{x:Null}" and Background="Transparent":

Background valueVisual resultHit testing
{x:Null}TransparentEmpty areas pass clicks through to windows behind
TransparentTransparentEmpty areas block clicks (the window captures all input)

This distinction applies at every level in Avalonia, from individual panels to the window itself. For more details, see Background and hit testing.

Migrating from WPF

In WPF, setting AllowsTransparency="True" with Background="Transparent" on a Window allows clicks to pass through transparent areas by default. Avalonia behaves differently: Background="Transparent" still captures input. Set Background="{x:Null}" instead to get the WPF-like click-through behavior.

Window Icon

<Window Icon="/Assets/app-icon.ico">

Or set it in code:

Icon = new WindowIcon(AssetLoader.Open(new Uri("avares://MyApp/Assets/app-icon.ico")));

Key Properties

PropertyTypeDescription
TitlestringWindow title bar text.
WindowStateWindowStateNormal, Minimized, Maximized, FullScreen.
WindowStartupLocationWindowStartupLocationManual, CenterScreen, CenterOwner.
SystemDecorationsSystemDecorationsFull, BorderOnly, None.
CanResizeboolWhether the user can resize the window.
CanMinimizeboolWhether the minimize button is enabled. Defaults to true.
CanMaximizeboolWhether the maximize button is enabled. Defaults to true. Automatically false when CanResize is false.
TopmostboolKeep the window above all others.
ShowInTaskbarboolShow in the OS taskbar.
IconWindowIconWindow icon for title bar and taskbar.
TransparencyLevelHintWindowTransparencyLevelRequested transparency: None, Transparent, Blur, AcrylicBlur, Mica.

See Also