DataGrid | Column Formatting
Reach for these before a CellTemplate / DataGridTemplateColumn. A template column gives up
sorting, filtering and inline editing; these keep all three, because the column still has a value —
it just knows how to render it.
DisplayAs picks a preset and Decimals tunes the numeric ones:
| Preset | Renders |
|---|---|
Currency |
$45,000.00 (Decimals="0" → $45,000) |
Percent |
15% — .NET’s "P" multiplies by 100, so store 0.15 |
Number |
1,234.5 |
Date / Time / DateTime |
short date / short time / general |
FileSize |
512 B, 1.5 KB, 5.0 MB |
Boolean |
a check/cross glyph, or your own TrueText / FalseText |
Enum |
the member’s [Description], else its name split on PascalCase (InProgress → In Progress) |
Text / None |
plain — Text also pins left alignment under Auto |
A raw .NET format string still works and wins over the preset: StringFormat on both hosts. MAUI
also accepts the older binding dialect (StringFormat="{}{0:C0}"), and Blazor’s original Format
parameter keeps working as an alias for StringFormat.
Around the formatted value: NullText replaces a null or empty value (prefix and suffix are not
applied to it — "$—" reads like a number), Prefix / Suffix decorate a real one, and Culture
overrides CurrentCulture for that column. When none of that fits, TextFormatter takes the raw value
and returns the string — the escape hatch that is still not a template, with prefix/suffix and
NullText applying around it.
@* Blazor *@<PropertyColumn Property="x => x.Salary" DisplayAs="DataGridColumnFormat.Currency" Decimals="0" /><PropertyColumn Property="x => x.Utilisation" DisplayAs="DataGridColumnFormat.Percent" Decimals="0" /><PropertyColumn Property="x => x.MailboxBytes" DisplayAs="DataGridColumnFormat.FileSize" /><PropertyColumn Property="x => x.LastReview" DisplayAs="DataGridColumnFormat.Date" NullText="—" /><PropertyColumn Property="x => x.State" DisplayAs="DataGridColumnFormat.Enum" /><PropertyColumn Property="x => x.Active" DisplayAs="DataGridColumnFormat.Boolean" Alignment="DataGridCellAlignment.Center" /><PropertyColumn Property="x => x.YearsOfService" Suffix=" yrs" /><PropertyColumn Property="x => x.Age" Title="Band" TextFormatter="@(a => a < 40 ? "Junior" : "Senior")" /><!-- MAUI --><shiny:DataGridColumn Title="Salary" PropertyName="Salary" DisplayAs="Currency" Decimals="0" /><shiny:DataGridColumn Title="Util." PropertyName="Utilisation" DisplayAs="Percent" Decimals="0" /><shiny:DataGridColumn Title="Reviewed" PropertyName="LastReview" DisplayAs="Date" NullText="—" /><shiny:DataGridColumn Title="State" PropertyName="State" DisplayAs="Enum" /><shiny:DataGridColumn Title="On" PropertyName="Active" DisplayAs="Boolean" Alignment="Center" /><shiny:DataGridColumn Title="Tenure" PropertyName="YearsOfService" Suffix=" yrs" /><shiny:DataGridColumn Title="Band" PropertyName="Age" TextFormatter="{Binding AgeBand}" />Alignment, wrapping and clamping
Section titled “Alignment, wrapping and clamping”Alignment defaults to Auto: quantities (Number, Currency, Percent, FileSize, and numeric
CLR types with no preset) align right, everything else left. HeaderAlignment follows Alignment
unless you set it, so a header sits over its own values. A numeric column that is really an identifier
— an account “number” — should say DisplayAs="Text", which pins it left.
Wrap lets a column’s text wrap instead of truncating on one line, and MaxLines caps how far it
grows. Every other column stays on its line.
<PropertyColumn Property="x => x.Notes" Wrap="true" MaxLines="2" /><shiny:DataGridColumn Title="Notes" PropertyName="Notes" Wrap="True" MaxLines="2" />Next Steps
Section titled “Next Steps”- Conditional Cell Styling — per-cell colour and weight from the row item
- Column Widths — pixels, stars and percentages


