Skip to content
Shiny Controls v1.0 - The Ultra Control Suite for .NET MAUI & BlazorO...M...G!

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 (InProgressIn 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 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" />