Skip to content

DataGrid

DataGrid derives directly from the native System.Windows.Controls.DataGrid rather than porting the web family’s headless state engine: the web’s NaviusDataGrid<TItem> renders no grid markup at all (no <table>, no ARIA, no keyboard model), leaving the actual grid surface to an out-of-repo styled layer, so the native WPF grid’s own row/column virtualization, ICollectionView-backed sort, SelectedItems, and DataGridAutomationPeer are used as-is. This control adds only a grid-level GlobalFilter and a RowKeySelector on top.

xmlns:datagrid="clr-namespace:Navius.Wpf.Primitives.Controls.DataGrid;assembly=Navius.Wpf.Primitives"
<StackPanel>
<TextBox x:Name="FilterBox" TextChanged="OnFilterChanged" />
<datagrid:NaviusDataGrid x:Name="Grid"
ItemsSource="{Binding Rows}"
GlobalFilter="{Binding ElementName=FilterBox, Path=Text}">
<datagrid:NaviusDataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" />
<DataGridTextColumn Header="Status" Binding="{Binding Status}" />
</datagrid:NaviusDataGrid.Columns>
</datagrid:NaviusDataGrid>
</StackPanel>

Columns are declared explicitly (AutoGenerateColumns = false), matching the web contract’s explicit Columns parameter.

Property Type Default From Description
GlobalFilter string? null NaviusDataGrid Controlled global filter text. Non-empty applies a predicate to the default ICollectionView over ItemsSource; empty or null clears it.
FilterFn Func<object, string, bool>? null NaviusDataGrid Optional per-instance match override. When unset, the default predicate is case-insensitive Contains against the ToString() of every public, readable, non-indexer instance property on the row (reflection cached per type). Mirrors the web’s per-column FilterFn, collapsed to one grid-level hook.
RowKeySelector Func<object, object>? null NaviusDataGrid Row identity selector (the web’s RowKey). Falls back to the row object itself as its own key when unset.
SortDescriptionsSnapshot IReadOnlyList<SortDescription> (read-only) - NaviusDataGrid Snapshot of Items.SortDescriptions, exposed as a convenience wrapper over the native multi-descriptor sort state (the web’s single-column DataGridSort has no direct WPF equivalent).
EnableRowVirtualization bool true System.Windows.Controls.DataGrid Set in the constructor and reasserted by the style; kept on so scale relies on native virtualization.
EnableColumnVirtualization bool true System.Windows.Controls.DataGrid Set in the constructor and reasserted by the style.
AutoGenerateColumns bool false System.Windows.Controls.DataGrid Columns are always explicit.
HeadersVisibility DataGridHeadersVisibility Column System.Windows.Controls.DataGrid No row-header gutter.
GridLinesVisibility DataGridGridLinesVisibility None System.Windows.Controls.DataGrid The style draws hairlines via row borders instead.
CanUserAddRows bool false System.Windows.Controls.DataGrid Read-only grid, no add-row affordance.
CanUserDeleteRows bool false System.Windows.Controls.DataGrid No delete-row affordance.
SelectionMode DataGridSelectionMode Extended System.Windows.Controls.DataGrid Closest native parity to the web’s set-based, multi-key row selection. Set explicitly in the constructor (matches the native default) so it is pinned by a test.
Method Description
GetRowKey(object row) Returns RowKeySelector?.Invoke(row) ?? row.
DefaultFilterMatch(object row, string filterText) Static, public: the default reflection-based match predicate, directly unit-testable without a live grid.

Riding entirely on the native System.Windows.Controls.DataGrid events (Sorting, SelectionChanged, CurrentCellChanged, and so on); this family adds no events of its own.

Riding entirely on the native System.Windows.Controls.DataGrid keyboard model (arrow-key cell navigation, click-to-sort on headers, Extended-selection modifiers). The web family implements no keyboard model of its own to port (its grid renders no markup), so there is no faithful-port obligation here beyond the native control’s defaults.

No custom automation peer: NaviusDataGrid inherits the native DataGridAutomationPeer, which reports AutomationControlType.DataGrid. The web family wires no ARIA grid semantics either (its NaviusDataGrid<TItem> renders no elements), so there is no existing role/name/pattern behavior to port; the native peer’s grid/row/cell pattern surface is used as-is. The unit suite (tests/Navius.Wpf.Tests/DataGridTests.cs, 23 tests) exercises the constructor defaults, the filter predicate, RowKeySelector fallback, and a perf-guard test (StyleApplication_PreservesVirtualization) that loads the real Themes/DataGrid.xaml dictionary onto a real instance and asserts row/column virtualization plus VirtualizingPanel.VirtualizationMode == Recycling survive the re-template.

  • The web’s NaviusDataGrid<TItem> is a pure headless state engine (global filter, single-column sort, pagination, row-selection, column-visibility) with zero rendered grid markup; the actual visual grid, keyboard model, and ARIA live in an out-of-repo styled layer. The WPF port instead derives from the native System.Windows.Controls.DataGrid, which already ships a full grid surface, so this is a re-template plus a thin state surface rather than a state-engine port.
  • Sorting is native multi-descriptor (Items.SortDescriptions), not the web’s single-column DataGridSort; SortDescriptionsSnapshot is a read-only convenience wrapper, not a settable parity property.
  • Pagination is deliberately not reimplemented: native WPF DataGrid has no built-in pager, and this pass is scoped as re-template plus thin state surface. All filtered/sorted rows render, relying on virtualization for scale; the web’s PageSize <= 0 “show all” special case is therefore N/A on this port.
  • The web’s per-column FilterFn is collapsed to one grid-level FilterFn hook; the web’s mixed- type ValueComparer for sorting is not ported, since sort comparison is left to the native ICollectionView.
  • Column reordering, resizing, and multi-column sort are native WPF DataGrid capabilities with no web-side equivalent to match or diverge from (the web family never implemented them).
  • Selection paints a full-row accent (Navius.Accent on DataGridRow.IsSelected, cell background transparent, foreground flipped via a DataTrigger bound to the ancestor row), a one-ink styling choice with no web-side visual to compare against (the web family renders no selection styling itself).

The DataGrid Gallery page rendered at the pinned commit, in each theme.

DataGrid Gallery page in the light theme

DataGrid Gallery page in the dark theme

DataGrid Gallery page in the high contrast theme