Data Table
A table filled from a list, with a filter, sortable columns, row selection and pages.
Installation
shellui-native add data-table
Platforms: MAUI · Avalonia. Also installs icon, button, table, input, checkbox.
Usage
Basic
Invoice | Customer | Status | Date | Amount | |
|---|---|---|---|---|---|
| INV001 | Shewart Shepherd | Paid | Sep 2, 2026 | ¤250.00 | |
| INV002 | ShellUI | Pending | Sep 5, 2026 | ¤150.00 | |
| INV003 | ShellIcons | Unpaid | Sep 9, 2026 | ¤350.00 | |
| INV004 | ShellDocs | Paid | Sep 12, 2026 | ¤450.00 | |
| INV005 | Shewart Shepherd | Paid | Sep 14, 2026 | ¤550.00 | |
| INV006 | ShellUI Native | Pending | Sep 18, 2026 | ¤200.00 | |
| INV007 | ShellUI | Unpaid | Sep 21, 2026 | ¤300.00 | |
| INV008 | ShellDocs | Paid | Sep 24, 2026 | ¤75.50 | |
| INV009 | ShellIcons | Paid | Sep 27, 2026 | ¤1,200.00 | |
| INV010 | ShellUI Native | Pending | Oct 1, 2026 | ¤89.99 |
Rows per page
<ui:DataTable ItemsSource="{Binding Invoices}" ShowSelection="True" MinimumContentWidth="560"
SelectionChanged="OnSelectionChanged" RowTapped="OnRowTapped">
<ui:DataTableColumn Header="Invoice" Property="Number" IsBold="True" Width="110" />
<ui:DataTableColumn Header="Customer" Property="Customer" Width="1.4*" />
<ui:DataTableColumn Header="Status" Property="Status" />
<ui:DataTableColumn Header="Date" Property="Date" Format="MMM d, yyyy" />
<ui:DataTableColumn Header="Amount" Property="Amount" Format="C" Width="120" HorizontalTextAlignment="End" />
</ui:DataTable><ui:DataTable ItemsSource="{Binding Invoices}" ShowSelection="True" MinimumContentWidth="560"
SelectionChanged="OnSelectionChanged" RowTapped="OnRowTapped">
<ui:DataTableColumn Header="Invoice" Property="Number" IsBold="True" Width="110" />
<ui:DataTableColumn Header="Customer" Property="Customer" Width="1.4*" />
<ui:DataTableColumn Header="Status" Property="Status" />
<ui:DataTableColumn Header="Date" Property="Date" Format="MMM d, yyyy" />
<ui:DataTableColumn Header="Amount" Property="Amount" Format="C" Width="120" HorizontalTextAlignment="End" />
</ui:DataTable>ItemsSource takes any list, and an ObservableCollection refreshes the table as it changes. Each column names the item property it shows:
public record Invoice(string Number, string Customer, string Status, DateTime Date, decimal Amount);
- Filter. Every word typed in the field must be in the text of some column.
- Sort. A sortable header cycles ascending, descending and unsorted. Numbers and dates sort by value.
- Selection.
ShowSelectionadds a checkbox column. The header checkbox selects every row that passes the filter, across pages.SelectedItemsholds the items, andSelectionChangedpasses them. - Pages. Ten rows at a time, with Previous and Next. Change the count with
PageSize, or turn pages off withShowPagination="False".
Cells show text only. For badges or buttons in cells, build the rows yourself with Table.
Columns
Width takes a Grid column width: *, 2* or a fixed number. Format is a .NET format string such as C or MMM d, yyyy. After changing an item's values in place, call Refresh().
Trimming and NativeAOT
Property is read by name at run time. In an app published with trimming or NativeAOT, set Value in code instead, so the property isn't trimmed away:
InvoiceTable.Columns[0].Value = item => ((Invoice)item).Number;
MAUI and Avalonia
- On Avalonia, sortable headers are tab stops, pressed with Enter or Space, and keep focus after sorting.
- On Avalonia a click on a row's checkbox doesn't raise
RowTapped.
API
DataTable
XAML children go to Columns.
| Property | Type | Default | Description |
|---|---|---|---|
ItemsSource |
IEnumerable (MAUI) · IEnumerable? (Avalonia) |
null |
The items to show, one row each. An ObservableCollection refreshes the table as it changes. |
ShowFilter |
bool |
true |
Shows the filter field above the table. |
FilterPlaceholder |
string |
"Filter..." |
Hint in the empty filter field. |
ShowPagination |
bool |
true |
Splits the rows into pages, with Previous and Next. |
PageSize |
int |
10 |
Rows per page while ShowPagination is on. |
ShowSelection |
bool |
false |
Adds a checkbox column; the header checkbox selects every row that passes the filter. |
EmptyText |
string |
"No results." |
Shown when no row passes the filter. |
MinimumContentWidth |
double |
0 |
Below this width the table scrolls sideways instead of squeezing its columns. 0 never scrolls. |
| Event | Arguments | Description |
|---|---|---|
SelectionChanged |
IReadOnlyList<object> |
The selection changed; passes the selected items. |
RowTapped |
object |
A row was tapped; passes its item. |
| Method | Description |
|---|---|
Refresh() |
Re-reads the items and columns. Call it after changing an item's values or a column. |
GoToPage(int page) |
Shows a page, counting from 1. |
SortBy(DataTableColumn? column, bool descending = false) |
Sorts by a column; call it again to reverse, and with null to restore the source order. |
ClearSelection() |
Unselects every row. |
DataTableColumn
| Property | Type | Default | Description |
|---|---|---|---|
Header |
string |
— | Text in the column's header cell. |
Property |
string |
— | The name of the item property this column shows. |
Value |
Func<object, object?>? |
null |
Reads the column's value from an item; replaces Property. Set it in code. |
Format |
string |
— | A .NET format string for the value, such as C or MMM d, yyyy. |
Width |
string |
"*" |
A Grid column width: *, 2* or a fixed number. |
IsSortable |
bool |
true |
Whether tapping the header sorts by this column. |
IsBold |
bool |
false |
Medium-weight text, for the row's key column. |
HorizontalTextAlignment |
TextAlignment |
Start |
Text alignment in the cell. |