Skip to content

Commit ec9ffd4

Browse files
w-ahmadCopilot
andcommitted
docs: align accessibility.md with new documentation set (PR w-ahmad#391)
- Resolve toc.yml merge conflict: add Accessibility entry under the new grouped Reference section from the PR w-ahmad#391 docs overhaul - Rewrite accessibility.md to match the Microsoft Learn / how-to style used by all new docs: xref links, 'When to use it', XAML/C# examples with tv: namespace prefix, 'Notes and limitations', 'Related articles' - Replace tvs: with tv: namespace prefix throughout - Add IValueProvider-on-edit-element note and Escape focus behaviour note (matching the fix made in the previous commit) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2 parents 71eb62f + 0e0bb9d commit ec9ffd4

42 files changed

Lines changed: 3388 additions & 183 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci-build.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ on:
88
- 'samples/**'
99
pull_request:
1010
branches: main
11-
paths-ignore:
12-
- 'docs/**'
13-
- 'samples/**'
1411

1512
jobs:
1613
build:

.github/workflows/ci-docs.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ on:
55
branches: main
66
paths-ignore:
77
- 'samples/**'
8+
pull_request:
9+
branches: main
10+
paths-ignore:
11+
- 'samples/**'
812

913
jobs:
1014
build:
@@ -30,11 +34,22 @@ jobs:
3034
- name: Build documentation
3135
run: docfx docs/docfx.json
3236

33-
- uses: actions/upload-pages-artifact@v3
37+
- name: Upload site artifact (PR preview)
38+
if: github.event_name == 'pull_request'
39+
uses: actions/upload-artifact@v4
40+
with:
41+
name: docs-site
42+
path: artifacts/_site
43+
retention-days: 14
44+
45+
- name: Upload pages artifact (deploy)
46+
if: github.event_name == 'push'
47+
uses: actions/upload-pages-artifact@v3
3448
with:
3549
path: artifacts/_site
3650

3751
publish-docs:
52+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
3853
needs: [build]
3954
environment:
4055
name: github-pages

docs/docs/accessibility.md

Lines changed: 103 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,185 +1,179 @@
11
# Accessibility
22

3-
TableView provides first-class accessibility support through UI Automation (UIA) peers for all its interactive elements. Screen readers, keyboard-only users, and accessibility testing tools can all navigate and interact with the control.
3+
`TableView` exposes a complete UI Automation (UIA) tree so that screen readers, keyboard-only users, and accessibility testing tools can navigate and interact with the control. Custom `AutomationPeer` classes are registered for every interactive element: the table itself, rows, cells, column headers, and row headers.
44

5-
## Supported UI Automation Patterns
5+
## When to use it
66

7-
| Element | UIA Patterns |
8-
|---------|-------------|
9-
| **TableView** | `GridPattern`, `TablePattern`, `SelectionPattern` (inherited) |
10-
| **TableViewRow** | `SelectionItemPattern` (inherited), `ExpandCollapsePattern` (when row details are available and `RowDetailsVisibilityMode` is `VisibleWhenExpanded`) |
11-
| **TableViewCell** | `GridItemPattern`, `TableItemPattern`, `SelectionItemPattern` |
12-
| **TableViewColumnHeader** | `InvokePattern` (when `CanSort` is `true`) |
13-
| **TableViewRowHeader** | _(structural header)_ |
7+
You do not need to opt in. Accessibility support is always active. This page explains what is exposed, how to improve automation names for custom content, and what limitations apply.
8+
9+
## Supported UIA patterns
10+
11+
| Element | UIA patterns |
12+
|---|---|
13+
| [`TableView`](xref:WinUI.TableView.TableView) | `GridPattern`, `TablePattern`, `SelectionPattern` (inherited from `ListView`) |
14+
| [`TableViewRow`](xref:WinUI.TableView.TableViewRow) | `SelectionItemPattern` (inherited), `ExpandCollapsePattern` when `RowDetailsVisibilityMode` is `VisibleWhenExpanded` |
15+
| [`TableViewCell`](xref:WinUI.TableView.TableViewCell) | `GridItemPattern`, `TableItemPattern`, `SelectionItemPattern` |
16+
| [`TableViewColumnHeader`](xref:WinUI.TableView.TableViewColumnHeader) | `InvokePattern` when [`CanSort`](xref:WinUI.TableView.TableViewColumnHeader.CanSort) is `true` |
17+
| `TableViewRowHeader` | Structural header element |
1418

1519
### GridPattern / TablePattern (TableView)
1620

17-
`TableView` exposes `IGridProvider` and `ITableProvider`:
21+
`TableView` implements `IGridProvider` and `ITableProvider`:
1822

19-
- **`RowCount`** — number of data rows (items)
23+
- **`RowCount`** — number of data rows currently loaded
2024
- **`ColumnCount`** — number of visible columns
21-
- **`GetItem(row, column)`** — returns the automation element for the specified cell (only for realized/visible cells)
25+
- **`GetItem(row, column)`** — returns the automation element for the specified cell (only for realized, on-screen cells)
2226
- **`GetColumnHeaders()`** — returns automation elements for all visible column headers
23-
- **`RowOrColumnMajor`**`RowMajor`
27+
- **`RowOrColumnMajor`**always `RowMajor`
2428

25-
### GridItemPattern / TableItemPattern (Cells)
29+
### GridItemPattern / TableItemPattern (cells)
2630

27-
Each `TableViewCell` exposes:
31+
Each `TableViewCell` exposes `IGridItemProvider` and `ITableItemProvider`:
2832

2933
- **`Row`** — zero-based row index
3034
- **`Column`** — zero-based column index
3135
- **`RowSpan` / `ColumnSpan`** — always 1
3236
- **`ContainingGrid`** — the owning `TableView`
3337
- **`GetColumnHeaderItems()`** — the column header for this cell
3438

35-
### SelectionItemPattern (Cells and Rows)
39+
### SelectionItemPattern (cells and rows)
3640

3741
- `IsSelected` reflects the current selection state
38-
- `Select()`, `AddToSelection()`, `RemoveFromSelection()` manipulate selection
42+
- `Select()`, `AddToSelection()`, and `RemoveFromSelection()` manipulate the selection programmatically
3943
- `SelectionContainer` returns the owning `TableView`
40-
- Row selection through `ListViewItemAutomationPeer` is provided automatically by the base `ListView` infrastructure
44+
- Row `SelectionItemPattern` is provided automatically by the base `ListView` infrastructure
4145

42-
### InvokePattern (Column Headers)
46+
### InvokePattern (column headers)
4347

44-
When a column is sortable (`CanSort = true`), its header exposes `IInvokeProvider`. Invoking the header cycles sort direction: ascending → descending → unsorted.
48+
When a column is sortable ([`CanSort`](xref:WinUI.TableView.TableViewColumnHeader.CanSort) is `true`), its header exposes `IInvokeProvider`. Invoking the header cycles the sort direction: ascending → descending → unsorted.
4549

46-
### ExpandCollapsePattern (Row Details)
50+
### ExpandCollapsePattern (row details)
4751

48-
When `RowDetailsVisibilityMode` is `VisibleWhenExpanded`, each row exposes `IExpandCollapseProvider` allowing programmatic expand/collapse of its details pane.
52+
When [`RowDetailsVisibilityMode`](xref:WinUI.TableView.TableView.RowDetailsVisibilityMode) is `VisibleWhenExpanded`, each row exposes `IExpandCollapseProvider` so automation clients can expand or collapse the details pane programmatically.
4953

50-
## Automation Names
54+
## Automation names
5155

5256
### TableView
53-
Uses `AutomationProperties.Name` if set; otherwise the name is inherited from the base `ListView` peer.
5457

55-
### Column Headers
56-
Format: `"{headerText}, {sortState}, {filterState}"` where sort and filter suffixes are omitted when not applicable.
58+
Uses [`AutomationProperties.Name`](https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.automation.automationproperties.name) if set; otherwise inherits from the base `ListView` peer.
5759

58-
Examples:
59-
- `"Name"` — unsorted, unfiltered
60-
- `"Name, Sort Ascending"` — sorted ascending
61-
- `"Name, Sort Descending, Filtered"` — sorted descending and filtered
60+
```xml
61+
<tv:TableView AutomationProperties.Name="Products table" />
62+
```
63+
64+
### Column headers
65+
66+
Format: `"{headerText}"`, with an optional sort-state suffix and filter suffix when applicable.
67+
68+
| State | Automation name example |
69+
|---|---|
70+
| Unsorted, unfiltered | `"Name"` |
71+
| Sorted ascending | `"Name, Sort Ascending"` |
72+
| Sorted descending | `"Name, Sort Descending"` |
73+
| Sorted and filtered | `"Name, Sort Descending, Filtered"` |
6274

6375
### Rows
64-
Format: `"Row {N}"` (1-based), or the value of `AutomationProperties.Name` if set.
6576

66-
The help text contains a summary of all cells: `"Name: Waheed Ahmad, Age: 30, City: London"`.
77+
Format: `"Row {N}"` (1-based index). The help text contains a summary of all cells in the row, for example `"Name: Waheed Ahmad, Age: 30, City: London"`.
6778

6879
### Cells
80+
6981
Format: `"{columnHeader}, Row {N}, {cellValue}"`.
7082

7183
Examples:
84+
7285
- `"Name, Row 3, Waheed Ahmad"`
7386
- `"Salary, Row 7, 95000"`
7487

75-
Override by setting `AutomationProperties.Name` on the cell's `CellStyle`:
88+
Override the name for a specific column by setting `AutomationProperties.Name` through a `CellStyle`:
7689

7790
```xml
78-
<TableView.CellStyle>
79-
<Style TargetType="tvs:TableViewCell">
80-
<Setter Property="AutomationProperties.Name" Value="Custom Cell Name" />
81-
</Style>
82-
</TableView.CellStyle>
91+
<tv:TableViewTextColumn Header="Status">
92+
<tv:TableViewTextColumn.CellStyle>
93+
<Style TargetType="tv:TableViewCell">
94+
<Setter Property="AutomationProperties.Name"
95+
Value="{Binding StatusDescription}" />
96+
</Style>
97+
</tv:TableViewTextColumn.CellStyle>
98+
</tv:TableViewTextColumn>
8399
```
84100

85-
### Row Headers
86-
Uses `AutomationProperties.Name` if set, otherwise the content of the row header as a string, or falls back to `"Row {N}"`.
101+
### Row headers
87102

88-
## Keyboard Navigation
103+
Uses `AutomationProperties.Name` if set on the `TableViewRowHeader`, otherwise derives the name from the header's content, or falls back to `"Row {N}"`.
89104

90-
TableView supports full keyboard navigation without breaking any existing behavior:
105+
## Keyboard navigation
91106

92107
| Key | Action |
93-
|-----|--------|
94-
| **Arrow Keys** | Move current cell / row |
95-
| **Tab / Shift+Tab** | Move to next/previous cell |
96-
| **Enter** | Move to next row cell (or commit edit) |
97-
| **Space** | Select/deselect current cell or row |
108+
|---|---|
109+
| Arrow keys | Move the current cell or row |
110+
| **Tab** / **Shift+Tab** | Move to the next / previous cell |
111+
| **Enter** | Move to the next row cell, or commit an edit |
112+
| **Space** | Select or deselect the current cell or row |
98113
| **F2** | Begin editing the current cell |
99-
| **Escape** | Cancel editing |
100-
| **Home / End** | Move to first/last column in row |
101-
| **Ctrl+Home / Ctrl+End** | Move to first/last row |
102-
| **Page Up / Page Down** | Move by one page |
114+
| **Escape** | Cancel editing and return focus to the current cell |
115+
| **Home** / **End** | Move to the first / last column in the row |
116+
| **Ctrl+Home** / **Ctrl+End** | Move to the first / last row |
117+
| **Page Up** / **Page Down** | Move by one page |
103118
| **Ctrl+A** | Select all |
104119
| **Ctrl+Shift+A** | Deselect all |
105120
| **Ctrl+C** | Copy to clipboard |
106121

107-
## Screen Reader Behavior
122+
## Screen reader behavior
108123

109-
When navigating with a screen reader (e.g. Narrator on Windows):
124+
When navigating with a screen reader such as Narrator:
110125

111-
1. **TableView** announces itself as a "table view" with row and column counts.
126+
1. Moving to the **TableView** announces it as a table with its row and column count.
112127
2. Moving between **rows** announces the row number and a summary of its content.
113-
3. Moving between **cells** announces the column header, row number, and current cell value.
114-
4. **Column headers** announce their header text along with the current sort state and filter state.
115-
5. **Editing**: When a cell enters edit mode, focus moves to the editing control (e.g. a `TextBox`), which announces itself to the screen reader independently with its own `IValueProvider`.
128+
3. Moving between **cells** announces the column header, row number, and current value.
129+
4. **Column headers** announce their header text, current sort state, and filter state.
130+
5. **Editing**: pressing **F2** (or double-tapping) enters edit mode. Focus moves to the editing control (for example, a `TextBox`), which announces itself independently with its own value. Pressing **Escape** returns focus to the cell, keeping Narrator on the correct cell.
116131
6. **Selection changes** are announced through `SelectionItemPattern.IsSelected`.
117132

118-
## How Developers Can Improve Automation Names
133+
## Custom automation names for template columns
119134

120-
### Custom Cell Names via Style
135+
`TableViewTemplateColumn` cells display developer-defined content. The cell automation name defaults to `"{columnHeader}, Row {N}"` unless overridden. Set `AutomationProperties.Name` directly on the root element of the template:
121136

122137
```xml
123-
<tvs:TableViewTextColumn Header="Status">
124-
<tvs:TableViewTextColumn.CellStyle>
125-
<Style TargetType="tvs:TableViewCell">
126-
<Setter Property="AutomationProperties.Name"
127-
Value="{Binding StatusDescription}" />
128-
</Style>
129-
</tvs:TableViewTextColumn.CellStyle>
130-
</tvs:TableViewTextColumn>
138+
<tv:TableViewTemplateColumn Header="Actions">
139+
<tv:TableViewTemplateColumn.CellTemplate>
140+
<DataTemplate>
141+
<Button Content="Edit"
142+
AutomationProperties.Name="Edit row" />
143+
</DataTemplate>
144+
</tv:TableViewTemplateColumn.CellTemplate>
145+
</tv:TableViewTemplateColumn>
131146
```
132147

133-
### Custom Column Header Names
148+
## Custom column header names
149+
150+
To override the automation name of a column header (for example, to provide a longer description for an abbreviated header):
134151

135152
```xml
136-
<tvs:TableViewTextColumn Header="DOB">
137-
<tvs:TableViewTextColumn.HeaderStyle>
138-
<Style TargetType="tvs:TableViewColumnHeader">
153+
<tv:TableViewTextColumn Header="DOB">
154+
<tv:TableViewTextColumn.HeaderStyle>
155+
<Style TargetType="tv:TableViewColumnHeader">
139156
<Setter Property="AutomationProperties.Name"
140157
Value="Date of Birth" />
141158
</Style>
142-
</tvs:TableViewTextColumn.HeaderStyle>
143-
</tvs:TableViewTextColumn>
144-
```
145-
146-
### Custom Row Header Names
147-
148-
```xml
149-
<tvs:TableView.RowHeaderTemplate>
150-
<DataTemplate>
151-
<!-- The TableViewRowHeader automation name derives from its content -->
152-
<TextBlock Text="{Binding EmployeeId}" />
153-
</DataTemplate>
154-
</tvs:TableView.RowHeaderTemplate>
155-
```
156-
157-
### Template Columns
158-
159-
For `TableViewTemplateColumn`, set `AutomationProperties.Name` directly on the template root element:
160-
161-
```xml
162-
<tvs:TableViewTemplateColumn Header="Actions">
163-
<tvs:TableViewTemplateColumn.CellTemplate>
164-
<DataTemplate>
165-
<Button Content="Edit"
166-
AutomationProperties.Name="Edit row" />
167-
</DataTemplate>
168-
</tvs:TableViewTemplateColumn.CellTemplate>
169-
</tvs:TableViewTemplateColumn>
159+
</tv:TableViewTextColumn.HeaderStyle>
160+
</tv:TableViewTextColumn>
170161
```
171162

172-
## Limitations
163+
## Notes and limitations
173164

174-
| Limitation | Notes |
175-
|------------|-------|
176-
| Virtualized cells | `IGridProvider.GetItem(row, column)` returns `null` for rows that are not currently realized in the visual tree. Scroll the target row into view first if needed. |
177-
| Cell value via IValueProvider | `IValueProvider` is not implemented on `TableViewCellAutomationPeer`. Instead, the editing element (e.g. `TextBox`) exposes `IValueProvider` when the cell is in edit mode. |
178-
| Non-Windows platforms | Automation peers are present on all platforms (WinUI 3 and Uno Platform). However, some automation clients and assistive technologies only run on Windows. |
179-
| Custom column types | `TableViewTemplateColumn` cells display developer-defined content; accessible names for those cells default to the column header + row index unless overridden by the template content. |
165+
- **Virtualized cells**: `IGridProvider.GetItem(row, column)` returns `null` for rows that are not currently in the visual tree. Scroll the target row into view before calling `GetItem`.
166+
- **IValueProvider on cells**: `IValueProvider` is not implemented on the cell peer. Instead, the editing element (for example, a `TextBox`) exposes `IValueProvider` while the cell is in edit mode.
167+
- **Custom column types**: cells in `TableViewTemplateColumn` show developer-defined content. Accessible names for those cells default to the column header and row index unless the template explicitly sets `AutomationProperties.Name`.
168+
- **Non-Windows platforms**: automation peers are compiled and run on all platforms (WinUI 3 and Uno Platform). However, not all Uno Platform targets expose a full UIA tree to assistive technologies. On WebAssembly (WASM), the platform relies on ARIA attributes managed by Uno. On Desktop Skia targets, accessibility support depends on the native platform's accessibility APIs.
180169

181-
## Uno Platform Notes
170+
## Related articles
182171

183-
Automation peers compile and run on all Uno Platform targets. However, not all Uno Platform targets expose a full UIA tree to assistive technologies. On WebAssembly (WASM), the platform relies on ARIA attributes which Uno manages separately. On Desktop Skia targets, accessibility support depends on the platform's native accessibility APIs.
172+
- [Selection](selection.md)
173+
- [Editing](editing.md)
174+
- [Sorting](sorting.md)
175+
- [Filtering](filtering.md)
176+
- [Row details](row-details.md)
177+
- [Row headers](row-headers.md)
178+
- [Styling rows, cells, and headers](styling.md)
184179

185-
If a particular automation pattern is not needed for non-Windows targets, guard it with `#if WINDOWS` as shown in the rest of the codebase.

0 commit comments

Comments
 (0)