This document specifies the current behavior and design of the Grid control as implemented.
For end-user usage and examples, see Grid.
Fixed(n), Auto, Star(weight).Min/Max constraints.Cells insertion order).GridRowDefinitions : BindableList<RowDefinition>ColumnDefinitions : BindableList<ColumnDefinition>Cells : BindableList<GridCell>Padding : ThicknessRowGap : intColumnGap : intAutoGrowRows : bool (default true)AutoGrowColumns : bool (default true)GridCellGridCell is a ContentVisual that carries placement information.
Row : int (clamped to >= 0)Column : int (clamped to >= 0)RowSpan : int (clamped to >= 1)ColumnSpan : int (clamped to >= 1)Content : Visual? (inherited from ContentVisual)HorizontalAlignment = Align.Stretch, VerticalAlignment = Align.Stretch.AutoGrowRows = true, AutoGrowColumns = true.RowDefinitions or ColumnDefinitions are empty, tracks default to Star(1).src/XenoAtom.Terminal.UI/Controls/Grid.cssrc/XenoAtom.Terminal.UI/Controls/GridCell.cssrc/XenoAtom.Terminal.UI/Layout/FlexAllocator.cssrc/XenoAtom.Terminal.UI.Tests/GridLayoutTests.cssamples/ControlsDemo/Demos/GridDemo.csRowDefinition.Height and ColumnDefinition.Width use GridLength with:
Fixed(n): track size is exactly n (after min/max clamping).Auto: track size is derived from the maximum child size in that track (span == 1), with no extra growth.Star(weight): like Auto for intrinsic sizing, but participates in growth when extra space is available.ColumnDefinition.MinWidth / MaxWidthRowDefinition.MinHeight / MaxHeightMin is always respected; Max is enforced when finite.
The effective row/column counts are derived from:
max(1, RowDefinitions.Count) and max(1, ColumnDefinitions.Count)(Row + RowSpan) / (Column + ColumnSpan) requested by any cellIf AutoGrowRows is false, the grid uses only the definition count (minimum 1) even if cells address rows beyond it.
The same applies to AutoGrowColumns.
If definitions exist but are fewer than the effective count, the missing tracks are implicitly Star(1).
Grid is a layout-only container:
RowGap and ColumnGap are clamped to >= 0.(rows - 1) * RowGap and (cols - 1) * ColumnGap (when there are at least 2 tracks).Grid.Measure runs a two-pass measure to support width-dependent heights (wrapping):
Only non-fixed tracks are influenced by cell measurement hints, and only for cells with span == 1.
For each row/column, the grid constructs arrays:
min[], natural[], max[]grow[], shrink[]The arrays are initialized from the track definitions:
Fixed: min/natural/max are set to the fixed size (clamped to min/max); grow/shrink are 0.Auto / Star:
min and natural are the track min (MinWidth/MinHeight)max is MaxWidth/MaxHeight (or infinite), normalized to be at least mingrow is 0 for Auto, and >= 1 for Star (from Star(weight) with a default weight of 1)shrink is 1Then, after measuring cells:
ColumnSpan == 1, the column's min/natural are updated to max of the cell hints.RowSpan == 1, the row's min/natural are updated to max of the cell hints.The grid then normalizes tracks so natural is clamped to [min..max] when max is finite.
During arrange, FlexAllocator.Allocate(...) computes the final integer sizes for each track:
min according to shrink weights.After allocation, the grid computes offsets using padding + gaps, then arranges each cell into its spanned rect.
When measuring with an unbounded width (max width is infinite), the grid treats Star columns as intrinsic:
availableForColumns = Sum(colNat) instead of infinite.This makes the grid report a meaningful desired width in unbounded measure scenarios (see GridLayoutTests.Unbounded_Measure_Treats_Star_Columns_As_Intrinsic).
Spans affect placement (the arranged rect size), but span > 1 does not contribute to track sizing:
min/natural of the spanned tracks during measure.This is a deliberate simplification in the current implementation and is a key limitation to keep in mind when authoring complex grids.
There is no GridStyle. Styling is achieved by wrapping the grid or individual cells (e.g., Border, Group, Rule), and by styling the cell content visuals.
None. Input routing and focus are handled by child visuals.
GridLayoutTests covers:
GridDemo shows typical form-like layouts using the fluent .Rows(...), .Columns(...), and .Cell(...) helpers.