From aa097e74f68768a9005b9a675cc442cca7dbe442 Mon Sep 17 00:00:00 2001 From: Asaf Mahlev Date: Wed, 28 Oct 2026 19:42:43 +0200 Subject: [PATCH 1/2] Make column headers reachable and usable from the keyboard Headers weren't tab stops, so keyboard and screen reader users couldn't sort, filter or group. The header row is now one tab stop with arrow keys between headers; Enter or Space sorts (Ctrl adds to the sort, as Ctrl+click does), and Alt+Down, Shift+F10 or the Menu key open the column's options. Right-click still follows UseRightClickForColumnFilter. Co-Authored-By: Claude Opus 5.5 --- src/TableViewColumnHeader.cs | 47 +++++++++++++++++++++++++++ src/Themes/TableViewColumnHeader.xaml | 2 +- src/Themes/TableViewHeaderRow.xaml | 2 ++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/TableViewColumnHeader.cs b/src/TableViewColumnHeader.cs index 17dd08ac..8ace1530 100644 --- a/src/TableViewColumnHeader.cs +++ b/src/TableViewColumnHeader.cs @@ -61,6 +61,7 @@ public TableViewColumnHeader() ManipulationMode = ManipulationModes.TranslateX; RegisterPropertyChangedCallback(WidthProperty, OnWidthChanged); RightTapped += OnRightTapped; + ContextRequested += OnContextRequested; } /// @@ -312,6 +313,52 @@ internal void HideFlyout() _optionsFlyout?.Hide(); } + /// + /// Keyboard access to what a click does: Enter or Space sorts (Ctrl adds to the existing sort, as Ctrl+click does), + /// and Alt+Down opens the column's options. Shift+F10 and the Menu key open them too (see OnContextRequested). + /// + protected override void OnKeyDown(KeyRoutedEventArgs e) + { + if (e.Key is VirtualKey.Enter or VirtualKey.Space && CanSort && Column is not null) + { + DoSort(GetNextSortDirection(), !IsKeyDown(VirtualKey.Control)); + e.Handled = true; + } + else if (e.Key is VirtualKey.Down && IsKeyDown(VirtualKey.Menu) && ShowOptions()) + { + e.Handled = true; + } + + base.OnKeyDown(e); + } + + /// + /// Opens the column's options for a keyboard context request (Shift+F10, the Menu key). A right-click also + /// raises this, with a pointer position; those keep going through . + /// + private void OnContextRequested(UIElement sender, ContextRequestedEventArgs e) + { + if (!e.TryGetPosition(this, out _) && ShowOptions()) + { + e.Handled = true; + } + } + + /// Opens the options flyout (sort, group, filter), if the column has one. + private bool ShowOptions() + { + if (_optionsButton?.Flyout is not { } flyout || !CanFilter) + { + return false; + } + + flyout.ShowAt(_optionsButton); + return true; + } + + private static bool IsKeyDown(VirtualKey key) => + InputKeyboardSource.GetKeyStateForCurrentThread(key).HasFlag(CoreVirtualKeyStates.Down); + /// protected override void OnTapped(TappedRoutedEventArgs e) { diff --git a/src/Themes/TableViewColumnHeader.xaml b/src/Themes/TableViewColumnHeader.xaml index fcc8c6f2..1e0b2916 100644 --- a/src/Themes/TableViewColumnHeader.xaml +++ b/src/Themes/TableViewColumnHeader.xaml @@ -33,7 +33,7 @@ + Value="True" /> diff --git a/src/Themes/TableViewHeaderRow.xaml b/src/Themes/TableViewHeaderRow.xaml index a7e6ab1f..6cd52787 100644 --- a/src/Themes/TableViewHeaderRow.xaml +++ b/src/Themes/TableViewHeaderRow.xaml @@ -15,6 +15,8 @@ From 436d1401ab0a14e5cb3ef5e49f0c090897e811f1 Mon Sep 17 00:00:00 2001 From: Asaf Mahlev Date: Wed, 28 Oct 2026 21:35:35 +0200 Subject: [PATCH 2/2] Document keyboard access to column headers Co-Authored-By: Claude Opus 5.5 --- docs/docs/accessibility.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/docs/accessibility.md b/docs/docs/accessibility.md index b028f5e0..20b611e1 100644 --- a/docs/docs/accessibility.md +++ b/docs/docs/accessibility.md @@ -119,6 +119,13 @@ Uses `AutomationProperties.Name` if set on the `TableViewRowHeader`, otherwise d | **Ctrl+Shift+A** | Deselect all | | **Ctrl+C** | Copy to clipboard | +The column header row is one tab stop: **Tab** to it, then move between headers with the **Left** / **Right** arrow keys. + +| Key (on a column header) | Action | +|---|---| +| **Enter** / **Space** | Sort by the column (cycles like a click); **Ctrl** adds to the existing sort, like **Ctrl**+click | +| **Alt+Down**, **Shift+F10** or the **Menu** key | Open the column's options (sort, group, filter) | + ## Screen reader behavior When navigating with a screen reader such as Narrator: