XAML and layout panels

How XAML maps to objects, the layout panels worth knowing, and the sizing rules that make a window resize gracefully.

XAML is object construction

XAML is XML that instantiates .NET objects. An element name is a type, an attribute is a property or an event, and nested elements are either children or property values. There is no hidden magic: the file is compiled into a partial class alongside your code-behind.

<Window x:Class="Shop.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Shop"
        Title="Inventory" Height="600" Width="900">
    <Window.Resources>
        <Style TargetType="Button">
            <Setter Property="Margin" Value="4" />
            <Setter Property="Padding" Value="10,4" />
        </Style>
    </Window.Resources>

    <Grid Margin="12">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Row="0" Grid.Column="0" Text="Search" VerticalAlignment="Center" />
        <TextBox   Grid.Row="0" Grid.Column="1" x:Name="SearchBox" Margin="6,0,0,0" />

        <ListBox   Grid.Row="1" Grid.ColumnSpan="2" ItemsSource="{Binding Results}"
                   DisplayMemberPath="Name" Margin="0,8" />

        <Button    Grid.Row="2" Grid.Column="1" Content="Search"
                   HorizontalAlignment="Right" Click="Search_Click" />
    </Grid>
</Window>
  • The default xmlns namespace is WPF itself; x: is the XAML language namespace and carries x:Name, x:Class and x:Key.
  • x:Name generates a field so code-behind can reference the element directly; a binding does not need it.
  • Attached properties such as Grid.Row are set on the child but interpreted by the parent panel.
  • Markup extensions in braces — {Binding ...}, {StaticResource ...}, {RelativeSource ...} — are how you reference a value computed at runtime rather than a literal.

Choosing a panel

PanelLayout ruleTypical use
GridRows and columns with star, auto or fixed sizingThe default for any real screen
StackPanelStacks children in one direction; children get their desired sizeSmall groups, toolbars, form field stacks
DockPanelDocks children to edges, last child fillsMenu bar, status bar, main content shell
WrapPanelFlows children and wraps to the next lineTag lists, thumbnail galleries
UniformGridEqual cells in a fixed gridKeypads, small tile boards
CanvasAbsolute positions, no resizingDiagram surfaces and overlays only
VirtualizingStackPanelStackPanel that recycles containersLong lists; the default inside ListBox

The single most common WPF mistake is nesting StackPanel everywhere. A StackPanel gives its children the space they ask for, so a DataGrid or ListBox inside it is measured with unlimited height and grows off-screen instead of scrolling.

💡
Use Grid with * rows and columns for anything that should fill available space, and reserve StackPanel for items whose natural size is the right size — buttons, labels, a legend.

Sizing and alignment

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />   <!-- as tall as content needs -->
        <RowDefinition Height="*" />      <!-- takes the remaining space -->
        <RowDefinition Height="2*" />     <!-- takes twice the space of the 1* row -->
        <RowDefinition Height="48" />     <!-- exactly 48 device-independent pixels -->
    </Grid.RowDefinitions>

    <Border Grid.Row="1" Background="#F3F4F6" Padding="8">
        <TextBlock Text="{Binding Status}"
                   TextWrapping="Wrap"
                   HorizontalAlignment="Stretch"
                   VerticalAlignment="Center" />
    </Border>

    <ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Auto">
        <ItemsControl ItemsSource="{Binding Orders}" />
    </ScrollViewer>
</Grid>
  • Star sizing makes the layout proportional; fixed pixels do not adapt to DPI or font scaling.
  • A control only fills its cell when HorizontalAlignment and VerticalAlignment are Stretch — the default for most controls, but not for StackPanel children measured against infinity.
  • MinWidth, MaxWidth and MinHeight on the window keep a layout usable at extreme sizes.
  • Wrap scrollable content in a ScrollViewer with an explicit grid row; a ScrollViewer inside a StackPanel collapses to its content height and never scrolls.
  • Sizes in XAML are device-independent pixels: at 150 percent scaling, 96 units render as 144 physical pixels.

FAQ

Grid or StackPanel for a form?
A Grid with an Auto label column and a * input column. Labels align, inputs stretch, and the layout survives a translated string that grows. Nested StackPanels do none of those things.
Why is my list not scrolling?
It is inside a StackPanel, or inside a ScrollViewer that itself has unlimited height. Give the list a * grid row, or keep the ScrollViewer as the immediate parent with a bounded height.

Data binding MVVM basics and commands

Last refreshed 2026-09-18.