WPF Standard Control Demo App › UniformGrid
UniformGrid Layout
UniformGrid places its children in cells of the same size, filling rows from left to right. Only the number of rows or columns is set; there are no row or column definitions.
How many rows and columns it makes
UniformGrid is in the System.Windows.Controls.Primitives namespace. Rows, Columns, and FirstColumn are 0 by default. For Rows and Columns, 0 means “work it out”: with neither set, UniformGrid made a square arrangement: for the demo app’s five labels it was 3 rows of 3 columns (cells 100 × 66.67 in a 300 × 200 grid), and the labels filled the first 2 rows, leaving the third row empty. Setting one of them fixes that dimension and adds the other as needed. In a grid 300 × 200, the five labels went into 5 rows of cells 300 × 40 with Columns="1", and 3 rows of cells 150 × 66.67 with Columns="2". With Rows="1" they went into one row of 5 columns, and with Rows="2" into 2 rows of 3 columns.
A Collapsed child takes no cell: with the second of five labels collapsed and Columns="2", the third label moved into the second cell, and 2 rows remained. Collapse a child to remove it from the grid.
What happens to children that do not fit
Set only one of Rows and Columns. When both are set and the children do not fit, the extra children are not dropped but placed outside the grid. With Rows="2", Columns="2", and five labels, the fifth was placed at (0, 200), below the four cells and outside the grid’s 200.
When FirstColumn is reset to 0
FirstColumn is the number of empty cells before the first child, which is how a calendar starts the first day of the month on its weekday. The demo app starts at 1 with Columns="3" and nine labels: the first label was in the second cell, (100, 0), the third label started the second row, and the grid had 4 rows.
Keep FirstColumn below Columns. With FirstColumn 3 or 4, not less than Columns, the grid reset it to 0: after layout the property read 0, the first label was at (0, 0), and the grid had 3 rows. The reset also removes a binding. With FirstColumn bound to a text box as in the demo app, typing 4 set it to 0 and removed the binding, and typing 1 afterwards left it at 0.
How large each cell is
Every cell has the same size. Stretched to 300 wide with three columns, the cells were 100 wide even with a child 150 wide in one of them. When the grid is sized to its content, the widest child sets the size of all cells: the same grid in a horizontal StackPanel had cells 150 wide. One large child therefore makes every cell as large.
Empty cells and ZIndex
With two columns and one label, a hit test in the empty cell found nothing with the default Background of null, and found the grid with Transparent. Where children overlap, Panel.ZIndex decides the order. In the demo app, the second label has a top margin of -15 and overlaps the first. With ZIndex 1 and 2, the second was on top; with 3 and 2, the first.
| case | measured |
|---|---|
| namespace / defaults: Rows, Columns, FirstColumn | System.Windows.Controls.Primitives / 0, 0, 0 |
| 5 labels, 300 x 200, Columns=1 (demo start) | 5 rows x 1 columns, cell 300 x 40 |
| 5 labels, 300 x 200, Columns=2 | 3 rows x 2 columns, cell 150 x 66.67 |
| 5 labels, 300 x 200, Rows=1 (demo start) | 1 rows x 5 columns, cell 60 x 200 |
| 5 labels, 300 x 200, Rows=2 | 2 rows x 3 columns, cell 100 x 100 |
| 5 labels, 300 x 200, neither set | 3 rows x 3 columns (children in 2 rows), cell 100 x 66.67 |
| 5 labels, Rows=2, Columns=2 (4 cells), 300 x 200: 4th / 5th label at | (150, 100) / (0, 200) |
| demo FirstColumn=1, Columns=3, 9 labels: Item1 / Item3 at, shape | (100, 0) / (0, 50), 4 rows x 3 columns |
| FirstColumn=3, Columns=3: Item1 at, shape; FirstColumn after layout | (0, 0), 3 rows x 3 columns; 0 |
| FirstColumn=4, Columns=3: Item1 at, shape; FirstColumn after layout | (0, 0), 3 rows x 3 columns; 0 |
| bound to text "4" (demo): FirstColumn, binding; text then "1": FirstColumn, Item1 at | 0, binding removed; 0, (0, 0) |
| 5 labels, Columns=2, Item2 Collapsed: Item3 at / shape | (150, 0) / 2 rows x 2 columns, cell 150 x 100 |
| Columns=3 with a child 150 wide: stretched to 300 / sized to content | 100 x 100 / 150 x 100 |
| Columns=2 with one label, Background=null: hit test in the empty cell | (nothing) |
| Columns=2 with one label, Background=Transparent: hit test in the empty cell | Grid |
| demo ZIndex labels (Item2 top margin -15), ZIndex 1 and 2: on top | Item2 |
| demo ZIndex labels (Item2 top margin -15), ZIndex 3 and 2: on top | Item1 |
Rows, columns, FirstColumn, and cell size. Measured on .NET 10 / Windows 11.
Trying it in the demo app

The UniformGrid page of the demo app has sections for Columns, Rows, FirstColumn, Background, and ZIndex. The “Show Code” link under each section displays its XAML. The following XAML is the FirstColumn section (UniformGridUsageControl.xaml), with the styles, the surrounding GroupBoxes, the input behavior of the text boxes, and six of the nine labels left out and the namespace declarations added:
<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TextBox x:Name="FirstColumnTextBox" Text="1" />
<TextBox x:Name="ColumnsForFirstColumnTextBox" Text="3" />
<UniformGrid x:Name="FirstColumnUniformGrid"
Columns="{Binding Text, ElementName=ColumnsForFirstColumnTextBox}"
FirstColumn="{Binding Text, ElementName=FirstColumnTextBox}">
<Label BorderBrush="Black" BorderThickness="1" Content="Item1" />
<Label BorderBrush="Black" BorderThickness="1" Content="Item2" />
<Label BorderBrush="Black" BorderThickness="1" Content="Item3" />
</UniformGrid>
</StackPanel>
Related controls and articles
Source code and how it was measured
Every behavior on this page was measured by running it on .NET 10 / Windows 11, using UniformGridDemoScene in this site’s screenshot tool, with labels like the demo app’s (border 1). The grids were laid out with Measure and Arrange, and rows and columns were counted from the children’s positions. Sizes are the values on the measuring machine.