Windows App Accessibility Basics — UI Automation and Preparing for Mandatory Reasonable Accommodation
· Updated: · Go Komura · Accessibility, UI Automation, Windows, WinForms, WPF, Reasonable Accommodation, Screen Readers, Disability Discrimination Act, Business Applications
Revision history (1 updates, last updated Sep 8, 2026)
A log of the changes made to this article. Where a pre-update version was archived, it stays readable at a permanent DOI link.
- Retranslated as a full translation of the current Japanese original. The previous English version was an abridgement that dropped subsections, tables, diagrams, and paragraphs; all of them have been restored to match the Japanese article, and the knowledge map section has been added where the Japanese article has one. The technical claims are the same as in the Japanese version. Read the version before this update (DOI: 10.5281/zenodo.22170885)
- First published
Cite this article(DOI: 10.5281/zenodo.22170884)
This article is archived on Zenodo. Below are both the DOI that always resolves to the latest version and the DOI pinned to the version you are reading.
Go Komura (2026). Windows App Accessibility Basics — UI Automation and Preparing for Mandatory Reasonable Accommodation. KomuraSoft LLC. https://doi.org/10.5281/zenodo.22170884 https://comcomponent.com/en/blog/windows-app-accessibility-ui-automation-guide/
- DOI (latest version)
- 10.5281/zenodo.22170884
- DOI (this version)
- 10.5281/zenodo.22652542
“A visually impaired employee cannot use our core order-entry app with a screen reader. They handle web browsers and email without trouble, but in our business app alone the announcements do not work.” We hear this kind of question from customers’ IT departments more and more often.
The starting point for solving this problem is to look at what you are telling assistive technology, not at how the screen looks. Windows has UI Automation (UIA), the mechanism through which screen readers read an app’s information. Once you understand how it works and cover the basics of names, keyboard, and color, the usability of a business app improves substantially.1
On the legal side, too, in-house Windows apps are not exempt. The 2021 amendment to the Act for Eliminating Discrimination against Persons with Disabilities took effect on April 1, 2024, and businesses too are now obligated to provide reasonable accommodation. The employment field, as in the opening example, falls under the Act on Employment Promotion of Persons with Disabilities instead and has been an employer obligation since April 2016. Chapter 2 sorts out this difference.23
Accessibility for Windows desktop apps has less information available than the web, and there is no way to solve it all at once after the fact. Much of the improvement needed, however, also raises the productivity of every user, with or without a disability.
This article is written for developers of Japanese business apps and IT department staff. It covers the legal framework and the standards and how UIA works, then moves on to WinForms/WPF implementation, keyboard operation, color and contrast, verification, and how to prioritize fixes.
flowchart TB
accTitle: The flow of this article
accDescr: The structure of this article, which connects in order the legal framework and standards, how UI Automation works, implementation in WinForms and WPF, keyboard operation, color and contrast, verification tools, and how to set priorities
law["Legal framework and standards"] --> uia["How UI Automation works"]
uia --> impl["Implementation in WinForms/WPF"]
impl --> kb["Keyboard operation"]
kb --> color["Color and contrast"]
color --> verify["Verification tools"]
verify --> prio["How to set priorities"]
Figure 1: This article connects the legal framework, the mechanism, implementation, verification, and priorities in a single flow.
1. The Bottom Line First
Three points to take in first.
- Separate individual reasonable accommodation from advance environmental improvement. Reasonable accommodation is a process of responding to a request through constructive dialogue, within a range that is not an excessive burden. Businesses have been obligated since April 2024, and employers in the employment field since April 2016. Fixing an app in advance counts as “environmental improvement” (a duty to make efforts), which is a different matter from making every screen perfect from the start.23
- The technical foundation is exposing information to UIA, plus the basics of names, keyboard, and color. The Name and ControlType of the UIA tree, and patterns such as Invoke, Value, and SelectionItem, are the material for announcement and operation. Naming comes first. WinForms handles it with AccessibleName and the association between a Label and the tab order, WPF with AutomationProperties.Name/LabeledBy; you also put keyboard operation, a color scheme guided by a 4.5:1 contrast ratio, and displays that do not rely on color alone in order.1456
- Verify and fix starting from the actual work. Combine FastPass in Accessibility Insights with hands-on checks using a screen reader, and work through the screens the user relies on, then new screens, then shared controls, in that order. The same improvements also help UI test automation such as FlaUI, which uses the same UIA foundation.7
The technical standards can be organized around WCAG. JIS X 8341-3:2016 is an identical standard with the same content as WCAG 2.0, and WCAG2ICT provides guidance on applying it to non-web software. Section 2.2 goes into the details.89
If you want to read according to your goal, start from the chapter below.
| Problem or goal | What to check | Chapter |
|---|---|---|
| Want to know what the “mandate” changed | The differences between reasonable accommodation, environmental improvement, and the employment field | Chapter 2 |
| Buttons and input fields are not announced correctly | UIA information and naming in each framework | Chapters 3-5 |
| Want to complete work without a mouse | Tab order, access keys, focus | Chapter 6 |
| Hard to use after changing colors or the scaling factor | Contrast, system colors, high DPI | Chapter 7 |
| Want to diagnose an existing app and decide the scope of fixes | Automated checks, hands-on checks, priorities, and records of dialogue | Chapters 8-9 |
In one sentence, accessibility support means “exposing correct names and operations on the UIA tree, and keeping to the basics of keyboard and color.”
In the diagram a solid line marks a relation that always holds and a dashed line marks a conditional one (the conditions are given per relation on the detail page). The full list of relations (16 in total, with evidence and certainty) and the definitions of the main concepts are collected on the knowledge map detail page (in Japanese). Data: JSON-LD / Turtle
2. The Legal Framework and the Standards — What the “Mandate” Changed
2.1. The Act for Eliminating Discrimination against Persons with Disabilities — Since April 2024, Businesses Too Must Provide Reasonable Accommodation
This section separates three questions: what became an obligation, where advance fixes fit, and which law applies in the employment field.
Reasonable Accommodation by Businesses Changed from a Duty to Make Efforts to an Obligation
The Act for Eliminating Discrimination against Persons with Disabilities prohibits administrative organs and businesses from “unjust discriminatory treatment” of persons with disabilities and requires them to “provide reasonable accommodation.” With the 2021 (Reiwa 3) amendment, the provision of reasonable accommodation by businesses, until then a duty to make efforts, became an obligation, and the amendment took effect on April 1, 2024 (Reiwa 6).2
The Cabinet Office leaflet explains it as responding, within a range that is not an excessive burden, when a person with a disability expresses the wish to have a barrier removed. Because the specifics differ by type of disability, scene, and situation, “constructive dialogue,” in which the person and the business talk it through and consider options together, is important. The leaflet states explicitly that unilaterally refusing dialogue can constitute a violation of the obligation to provide accommodation.2
Treat Advance App Fixes as “Environmental Improvement”
Having everything in place in advance is not what became an obligation. Measures taken in advance for an unspecified number of persons with disabilities, such as revising manuals, training, and making facilities barrier-free, are called “environmental improvement” and are positioned as a duty to make efforts.2
Putting a business app in a state a screen reader can use ahead of time can be regarded as an effort on this environmental-improvement side. The further that improvement has gone, the lighter the burden of providing individual reasonable accommodation.
Where Employees Are Involved, Look at the Act on Employment Promotion of Persons with Disabilities
Employment and work are covered by the Act on Employment Promotion of Persons with Disabilities, not by the Act for Eliminating Discrimination against Persons with Disabilities. The Cabinet Office leaflet notes this distinction as well.2
Under the Act on Employment Promotion of Persons with Disabilities, the amendment that took effect in April 2016 (Heisei 28) obligates employers to refrain from disability discrimination in employment and to provide reasonable accommodation within a range that is not an excessive burden. The opening question, “an employee cannot use the business app,” has therefore been in the territory of obligation since well before 2024.3
flowchart TB
accTitle: Where reasonable accommodation and environmental improvement fit
accDescr: The relationship between a general business and a person with a disability falls under the Act for Eliminating Discrimination against Persons with Disabilities, and providing reasonable accommodation by responding to an individual request through constructive dialogue has been an obligation since April 2024; the employment field has been an employer obligation since April 2016 under the Act on Employment Promotion of Persons with Disabilities; fixing an app in advance counts as environmental improvement, a duty to make efforts
scene{"Which scene?"} -->|Business and a person with a disability| kaisho["Act for Eliminating Discrimination against Persons with Disabilities"]
scene -->|Employment and work| koyou["Act on Employment Promotion of Persons with Disabilities"]
kaisho --> moushide["Respond to individual requests through constructive dialogue"]
moushide --> hairyo["Provision of reasonable accommodation (obligation since April 2024)"]
koyou --> koyougimu["Provision of reasonable accommodation (obligation since April 2016)"]
kaisho -.-> kankyo["Advance app fixes = environmental improvement (duty to make efforts)"]
kankyo -.-> moushide
Figure 2: The governing law depends on the scene; reasonable accommodation is an obligation, and advance fixes count as environmental improvement, a duty to make efforts.
How an individual case is treated in law depends on the situation. This article does not go into legal interpretation; it proceeds from the standpoint of what an engineer can do when asked to respond. For primary sources, see the materials from the Cabinet Office and the Ministry of Health, Labour and Welfare.23
2.2. JIS X 8341-3 and WCAG — The “Web Criteria” Extend to Software Too
When you read the technical standards in detail, organizing them around WCAG gives the clearest view. JIS X 8341-3:2016, WCAG, and WCAG2ICT relate to each other as follows.869
| Standard or document | Position | How this article uses it |
|---|---|---|
| JIS X 8341-3:2016 | An identical standard of ISO/IEC 40500:2012; the body of the standard has the same content as WCAG 2.0 | Grasp the technical standards for accessibility |
| WCAG | The document that defines the success criteria. Extended from 2.0 to 2.1/2.2, with a Japanese translation by WAIC | Check concretely what has to be done |
| WCAG2ICT | A W3C Group Note on applying WCAG 2.0/2.1/2.2 to non-web documents and software | Apply the same thinking to a desktop app |
To the question “isn’t WCAG a standard for web content?”, WCAG2ICT is the bridge. Its full name is Guidance on Applying WCAG 2 to Non-Web Information and Communications Technologies.9
Ideas such as text alternatives, contrast, keyboard operation, and not conveying information by color alone apply to a Windows desktop app in the same framework. From Chapter 3 on, this article turns them into WinForms/WPF implementation.
flowchart TB
accTitle: The relationship between JIS X 8341-3 and WCAG
accDescr: JIS X 8341-3:2016 is an identical standard with the same content as WCAG 2.0, and WCAG2ICT shows how to apply the WCAG success criteria to non-web software, so a Windows desktop app can be inspected in the same framework
wcag["WCAG 2.0 (W3C)"] ---|Identical standard with the same content| jis["JIS X 8341-3:2016"]
wcag --> ict["WCAG2ICT"]
ict --> soft["Applied to non-web software"]
soft --> app["Windows desktop apps"]
Figure 3: JIS X 8341-3:2016 is an identical standard of WCAG 2.0, and WCAG2ICT extends the same criteria to desktop apps.
3. How Assistive Technology Reads an App — The UI Automation Trio
3.1. The UIA Tree, Properties, and Control Patterns
UI Automation (UIA), built into Windows, is the accessibility foundation that mediates between the app and assistive technology. The app exposes UI information as a “provider,” and assistive technology such as a screen reader obtains it as a “client.” UI operation by means other than standard input is also made possible by this mechanism.1
Start by understanding it as a trio: the structure of the screen, the nature of each element, and the operations available.1
| Element | Role | Typical examples |
|---|---|---|
| UIA tree | A tree with the desktop as its root, running from window to control. Assistive technology walks this tree to understand the UI | Window, pane, button, edit box |
| Properties | Values that describe the nature of each element | Name (purpose), ControlType (kind), AutomationId (identifier), IsEnabled, IsKeyboardFocusable |
| Control patterns | A vocabulary of “available operations” per kind | Invoke (press), Value (read/write a value), SelectionItem (select), Toggle (on/off), ExpandCollapse (expand/collapse) |
For example, the announcement “Confirm order, button” when a button receives focus is roughly the combination of Name and control type. When the user issues an execute command, assistive technology presses the button through the Invoke pattern.
In other words, a button being drawn on screen and a button being readable and operable by assistive technology are two different things. If Name and the patterns are not exposed correctly, the button might as well not exist, even though it is visible on screen.
flowchart TB
accTitle: The UI Automation trio
accDescr: The app, as a provider, exposes each element's properties and control patterns on the UIA tree; the screen reader, as a client, announces Name and ControlType and operates through patterns such as Invoke
app["App (provider)"] --> tree["UIA tree"]
tree --> prop["Properties (Name, ControlType, etc.)"]
tree --> pat["Patterns (Invoke, Value, etc.)"]
sr["Screen reader (client)"] -->|Announces| prop
sr -->|Operates| pat
Figure 4: The screen reader uses the properties and patterns the app exposed on the UIA tree for announcement and operation.
3.2. A Screen Reader Is a UIA Client
The main screen readers on Windows are the built-in Narrator, the free and open-source NVDA,10 and PC-Talker, a commercial product widely used in Japan.
Each has its own style of announcement, but the primary path for reading a desktop app’s UI is UIA in every case. The app-side work therefore comes down to exposing correct information to UIA, rather than targeting any particular screen reader.
flowchart TB
accTitle: The common path of the main screen readers
accDescr: If the app exposes correct information to UIA, Narrator, NVDA, and PC-Talker can all read the UI by the same path, so the app-side work is not aimed at a particular screen reader but comes down to exposing information to UIA
app["App"] -->|Exposes information| uia["UI Automation (UIA)"]
uia --> nar["Narrator"]
uia --> nvda["NVDA"]
uia --> pct["PC-Talker"]
app -.-> goal["The work comes down to exposing to UIA"]
Figure 5: The main screen readers all go through UIA, so the app’s work comes down to exposing information to UIA.
3.3. What Is a “Button with an Empty Name” Announced As?
Suppose a toolbar has a Save button that shows only a floppy-disk icon. Even though the purpose is clear visually, if Name is left empty the screen reader announces nothing more than “button”. If the neighboring “Open” and “Print” are in the same state, the user hears only “button, button, button” and cannot tell them apart.
Buttons without a Name and images announced only as “Image” are listed in Microsoft’s fix guides as typical problems that stop the user’s work.5
Standard WinForms/WPF controls support UIA from the start, and for most of them Name is derived automatically from text or a label. The three typical ways it breaks are as follows.
| Typical cause | What to check |
|---|---|
| Icon only, with no material for a name | Whether a name for announcement is set explicitly |
| No association with a label | Whether the input field is associated with its display label |
| Custom drawing that exposes no information | Whether meaningful information appears in the UIA tree |
The next two chapters connect this triage to the fixes for WinForms and WPF respectively.
flowchart TB
accTitle: Three typical ways announcement breaks
accDescr: Announcement breaks when there is no material for a name because the control is icon only, when there is no association with a label, or when custom drawing puts no information on the UIA tree, and the control ends up announced only as button
c1["Icon only, no material"] --> broken["Name ends up empty"]
c2["No label association"] --> broken
c3["Custom drawing exposes nothing"] --> broken
broken --> result["Announced only as button"]
Figure 6: Broken announcements usually come down to three patterns: missing material for a name, missing association, or custom drawing.
4. Implementation in WinForms — AccessibleName and Tab Order
4.1. Controls Whose Text Becomes Name Automatically, and Controls Whose Text Does Not
First, Check Whether the Control Is a Kind Whose Text Is Used as the Name
In WinForms, even among controls that display text, some use Text as the UIA Name and some do not.4
| Example controls | How Name is handled |
|---|---|
| Button, CheckBox | The value of the Text property is used as Name |
| ComboBox, ListBox, ListView, PictureBox, ProgressBar, TabControl, TextBox, TreeView | Text does not become Name, so give the name by another means |
Use a Display Label, and Set AccessibleName Where You Cannot Place One
The easiest approach to maintain is to place a descriptive Label immediately before the target control in the tab order. If the target control’s TabIndex comes directly after the Label’s TabIndex, the Label’s text is used as the UIA Name. The display and the announcement match, and you avoid maintaining the wording twice.411
Where you cannot place a Label, set AccessibleName explicitly. You can also set AccessibleDescription for supplementary information, and AccessibleRole when the role needs to match what the control actually does.12
flowchart TB
accTitle: How a WinForms control's name is decided
accDescr: For Button and similar controls, Text becomes the UIA Name as is; for controls such as TextBox whose Text is not reused, the text of a Label placed immediately before in the tab order is used; where a Label cannot be placed, AccessibleName is set explicitly
ctrl["Control"] --> qtext{"Text becomes Name?"}
qtext -->|Yes| usetext["Text is used as Name as is"]
qtext -->|No| qlabel{"Label immediately before in tab order?"}
qlabel -->|Yes| uselabel["The Label's text is used as Name"]
qlabel -->|No| explicit["Set AccessibleName explicitly"]
Figure 7: A WinForms Name is decided in the order Text, the Label immediately before in the tab order, then AccessibleName.
// Icon-only toolbar button: set the name for announcement explicitly
saveToolStripButton.AccessibleName = "Save";
// Image-only button: name plus supplementary description
btnSearchCustomer.AccessibleName = "Search customers";
btnSearchCustomer.AccessibleDescription = "Searches the customer master by customer code or name";
// Input field where a Label cannot be placed immediately before it in the tab order: set it directly
txtOrderNo.AccessibleName = "Order number";
// PictureBox repurposed as a chart: match the role to what it actually is
pictureBoxChart.AccessibleRole = AccessibleRole.Chart;
pictureBoxChart.AccessibleName = "Monthly order count chart";
When You Cleared the Name but the Default Announcement Does Not Come Back
If you set AccessibleName once in the Visual Studio Properties pane and then clear it, a setting with an empty string may remain in the designer file. If that setting blocks the default name resolution, delete the line from the designer file.4
flowchart TB
accTitle: The problem of an empty-string AccessibleName remaining
accDescr: If you set AccessibleName once in the Properties pane and then clear it, an empty-string setting remains in the designer file and blocks the default name resolution, so you fix it by deleting the line from the designer file
set["Set AccessibleName"] --> erase["Clear it in the Properties pane"]
erase --> remain["An empty-string setting remains"]
remain --> block["Blocks the default name resolution"]
block -.-> fix["Delete the line from the designer file"]
Figure 8: Clearing the value in the Properties pane leaves an empty string behind, so fix it by deleting the line from the designer file.
4.2. Common Improvements on an Order-Entry Screen
Here is a checklist of the places we most often fix in business apps.
| Common state | Problem | Fix |
|---|---|---|
| Icon-only ToolStripButton | Announced only as “button” | Set AccessibleName |
| A Label sits near the TextBox but the tab order is scattered | The input field’s name is empty or unrelated | Place the input field directly after the Label’s TabIndex |
| A PictureBox used as a button through Click | The role is not conveyed as a button, and it cannot be pressed from the keyboard | Replace it with a Button, or set AccessibleRole/AccessibleName and add keyboard support |
| DataGridView column headers are empty or symbols only | The meaning of the column is lost when a cell is announced | Set a meaningful column name in HeaderText |
| Only a Panel groups the contents, and the heading is an image | Cannot tell which group of inputs it is | Use a GroupBox, or make the heading a Label |
Each is a fix of a few lines, but for a screen reader user it is the difference between a screen they cannot use and one they can.
5. Implementation in WPF — AutomationProperties and AutomationPeer
5.1. AutomationProperties.Name / LabeledBy / HelpText
Give a Button Its Name Through String Content or an Explicit Setting
In a control whose Content is a string, such as a WPF Button, that content is used as the UIA Name. A button containing only an Image or a Path, on the other hand, has no material for a name. Either set it explicitly with AutomationProperties.Name, or, if display text is nearby, associate it with AutomationProperties.LabeledBy.5
In a TextBox, Separate the “Name” from the “Input Value”
A TextBlock’s Text is reused as Name, but a TextBox’s Text is exposed on the UIA Value property and does not become Name. Even when the field holds a value, that alone does not tell the user what the field is for.13
For an input field, the first choice is to associate the display-label TextBlock through LabeledBy. The display and the announcement match, and you avoid maintaining the wording twice.13
<!-- Input field: associate the display label through LabeledBy -->
<TextBlock x:Name="OrderNoLabel" Text="Order number" />
<TextBox
AutomationProperties.LabeledBy="{Binding ElementName=OrderNoLabel}"
AutomationProperties.AutomationId="OrderNoTextBox" />
<!-- Icon-only button: set the name explicitly and add a supplement if needed -->
<Button
AutomationProperties.Name="Confirm order"
AutomationProperties.HelpText="Confirms the order being entered and allocates inventory">
<Path Data="{StaticResource CheckIconGeometry}" Width="16" Height="16" />
</Button>
flowchart TB
accTitle: How a WPF control's name is decided
accDescr: A control whose Content is a string uses that content as Name; otherwise the first choice is to associate a nearby display label through LabeledBy, and if there is none, AutomationProperties.Name is set explicitly; a TextBox's Text is exposed as Value, not as Name
ctrl["Control"] --> qc{"Content is a string?"}
qc -->|Yes| auto["The content becomes Name"]
qc -->|No| ql{"Display label nearby?"}
ql -->|Yes| lb["Associate through LabeledBy"]
ql -->|No| nm["Set Name explicitly"]
tbx["TextBox Text"] -.-> val["Exposed as Value, not Name"]
Figure 9: A WPF Name is decided in the order string Content, LabeledBy, then an explicit setting; a TextBox’s Text does not become Name.
HelpText and AutomationId Play Different Roles from the Name
Supplementary information that does not fit in Name is exposed through AutomationProperties.HelpText.5 AutomationId is an identifier that is also used to locate elements in UI test automation. Deciding a naming convention at the screen-design stage pays off in later tests.
In short, Name is the purpose, HelpText is the supplement, and AutomationId is the identifier. How they are used in automated tests is covered in detail in “UI Automated Testing for Windows Desktop Apps”.
5.2. Custom Controls Need an AutomationPeer
A custom-drawn control cannot, by itself, expose meaningful information on the UIA tree. In WPF, you expose name, kind, and patterns by overriding OnCreateAutomationPeer on a UIElement-derived class and returning an AutomationPeer-derived class.14
If you inherit from an existing control, inherit from the corresponding Peer as well. For ButtonBase, for example, using ButtonBaseAutomationPeer lets you carry over the behavior that is already implemented.14
flowchart TB
accTitle: How AutomationPeer exposes information
accDescr: A custom control exposes name, kind, and patterns by overriding OnCreateAutomationPeer and returning an AutomationPeer-derived class; if it inherits an existing control, it inherits the corresponding Peer and carries over the behavior that is already implemented
custom["Custom control"] --> ov["OnCreateAutomationPeer"]
ov --> peer["Return a Peer-derived class"]
peer --> pub["Expose name, kind, and patterns"]
inherit["Inherits an existing control"] -.-> basepeer["Inherit the corresponding Peer"]
basepeer -.-> reuse["Carry over implemented behavior"]
Figure 10: A custom control returns a Peer from OnCreateAutomationPeer to expose information to UIA.
// Example of a control that custom-draws the line status as a colored lamp
public class StatusLamp : Control
{
public static readonly DependencyProperty IsOnlineProperty =
DependencyProperty.Register(nameof(IsOnline), typeof(bool), typeof(StatusLamp),
new FrameworkPropertyMetadata(false,
FrameworkPropertyMetadataOptions.AffectsRender, OnIsOnlineChanged));
public bool IsOnline
{
get => (bool)GetValue(IsOnlineProperty);
set => SetValue(IsOnlineProperty, value);
}
internal static string NameFor(bool isOnline)
=> isOnline ? "Line status: online" : "Line status: offline";
private static void OnIsOnlineChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// Raise the UIA property-changed event the moment the value changes. Without it,
// the screen reader keeps the old name and never notices the change of state
if (UIElementAutomationPeer.FromElement((UIElement)d) is AutomationPeer peer)
{
peer.RaisePropertyChangedEvent(
AutomationElementIdentifiers.NameProperty,
NameFor((bool)e.OldValue), NameFor((bool)e.NewValue));
}
}
protected override AutomationPeer OnCreateAutomationPeer()
=> new StatusLampAutomationPeer(this);
}
public class StatusLampAutomationPeer : FrameworkElementAutomationPeer
{
public StatusLampAutomationPeer(StatusLamp owner) : base(owner) { }
protected override AutomationControlType GetAutomationControlTypeCore()
=> AutomationControlType.Text; // Text is appropriate for a status display with no operations
protected override string GetNameCore()
=> StatusLamp.NameFor(((StatusLamp)Owner).IsOnline);
}
Notify State Changes, Not Just the Current Name
The example above combines two things: returning a name that reflects the current state, and raising a Name property-changed event when IsOnline changes.
The Peer’s job is not only to return the name but also to signal the change with an event the moment it happens. Assistive technology has no timing of its own for re-fetching a value, so without the event the implementation is “correct only when asked again,” and screen reader users never learn that the state has changed.
sequenceDiagram
accTitle: How a state change reaches the screen reader
accDescr: The moment the control's value changes, the AutomationPeer raises a Name property-changed event; assistive technology does not re-fetch on its own, so without the event it keeps the old name and never notices the change
participant c as Control
participant p as AutomationPeer
participant s as Screen reader
c->>p: IsOnline value changes
p->>s: Raises a Name property-changed event
s->>s: Announces the new state
Note over s: Without the event, the old name stays
Figure 11: A change of value reaches the screen reader only when the AutomationPeer signals it with a change event.
If the Control Has Operations, Implement the Patterns and Put Them in Shared Components
For custom controls that can be pressed, have a changeable value, or can be selected, override GetPattern and provide pattern interfaces such as IInvokeProvider and IRangeValueProvider.14
If you build the Peer into the shared control library, every screen that uses it becomes compliant automatically. That is the foundation for the rollout described in Chapter 9.
6. Can Every Function Be Reached from the Keyboard Alone?
WCAG success criterion 2.1.1 (Keyboard) requires that all functionality be operable through a keyboard interface.6 Screen reader users generally do not use a mouse, so a function that cannot be reached from the keyboard is the same as a function that does not exist.
6.1. Check Movement, Execution, and Current Position
Check not only the tab order but also that the main operations can be executed and that the current focus is visible.
| Aspect | What to check | Main means in WinForms / WPF |
|---|---|---|
| Tab order | Does Tab move in the same order as the visual layout (top left to bottom right)? | Tidy TabIndex, set TabStop |
| Access keys | Can Alt plus a letter jump directly to the main items? | & in Text for WinForms, _ in the header for WPF |
| Shortcuts | Do frequent operations (save, search, confirm) have a dedicated key? | Assign Ctrl+S and the like, and show them in the menu |
| Focus indication | Can the user see where the focus is right now? | Do not remove the focus rectangle; draw it yourself when custom-drawing |
| Mouse-only functions | Is any function available only by double-click, right-click, drag, or hover? | Offer the same function through a menu or key as well |
| Dialogs | Do Enter = default button and Esc = cancel work? | AcceptButton/CancelButton, IsDefault/IsCancel |
The WinForms accessibility walkthrough also lists, as basics, placing a label immediately before an input field in the tab order and giving access keys to the controls and menus the user wants to move to.11
6.2. Keyboard Work Also Improves Input Efficiency for Every User
This is not merely “an extra cost for supporting people with disabilities.” In routine work such as order entry, whether the operator can complete input without leaving the home position decides how many transactions they get through.
A scrambled tab order or an operation that requires the mouse is a defect that shaves a little off every user’s productivity every day. Accessibility work and keyboard efficiency are two names for the same work. For priorities by usage environment, see also “Windows App UX Design”.
flowchart TB
accTitle: The dual effect of keyboard work
accDescr: Putting tab order, access keys, and focus indication in order produces two effects at once, assistive technology users being able to reach functions and the input speed of every operator, while a function usable only with the mouse is the same as a function that does not exist
seibi["Keyboard operation put in order"] --> a11y["Assistive technology users can work"]
seibi --> speed["Input speed of every operator"]
mouse["Mouse-only functions"] -.-> none["Same as nonexistent functions"]
Figure 12: Keyboard work delivers assistive technology support and efficiency for every user at once; a mouse-only function is as good as nonexistent.
7. Color and Contrast — 4.5:1 and “Not by Color Alone”
7.1. The Contrast Ratio Guideline Is 4.5:1
WCAG success criterion 1.4.3 (Contrast (Minimum)) requires a contrast ratio of at least 4.5:1 for text and images of text, and at least 3:1 for large text.6
Designs that put light gray text on a white background fall short of this criterion more often than you might think. Keep in mind people whose vision and color perception have changed with age and people who work in poorly lit places such as factories, and make it a habit to measure with a contrast checker during design review.
7.2. Do Not Convey Information by Color Alone
Success criterion 1.4.1 (Use of Color) says that color must not be the only visual means of conveying information.6 Typical cases in business apps are as follows.
| Conveyed by color alone | Additional means |
|---|---|
| Error rows shown only in red text | An error icon and a message column |
| Required fields shown only by the label color | An asterisk or the word “Required” |
| Status shown only by the color of a lamp | Color plus shape, or text such as “Running” and “Stopped” |
Considering the diversity of color vision, this too is a basic of display design rather than a “special measure.”
flowchart TB
accTitle: Replacing information conveyed by color alone
accDescr: A display that shows errors only in red text is replaced with an error icon and a message column alongside, a display that shows required fields only by label color gets a Required marker added, and a display that shows status only by lamp color is replaced with shape or text alongside the color
err["Errors in red text only"] --> erra["Add an icon and wording"]
req["Required by label color only"] --> reqa["Add a Required marker"]
lamp["Status by lamp color only"] --> lampa["Combine color with shape or text"]
Figure 13: Replace the typical color-only cues with an icon, a marker, or shape and text alongside the color.
7.3. Following Contrast Themes (High Contrast)
Windows contrast themes (formerly high contrast) are color schemes that separate foreground and background strongly. The built-in themes are designed for a contrast ratio of roughly 7:1 or more, and users can select and edit them.15
On the app side, do not hard-code colors; respect the system colors. What to do in each framework is as follows.
| Framework | Basic color scheme | What to check when you have custom colors |
|---|---|---|
| WinForms | Leave ForeColor/BackColor at their defaults so the user’s color settings are used | Detect SystemInformation.HighContrast and switch to a SystemColors-based scheme, then follow setting changes through UserPreferenceChanged |
| WPF/WinUI | Reference the SystemColors family of resources to follow theme switches | Check whether areas filled with custom brushes are what breaks the layout |
For the concrete WinForms settings see Microsoft’s walkthrough, and for the theme colors see the contrast themes documentation.1115
flowchart TB
accTitle: Following contrast themes
accDescr: Places where colors are hard-coded break when switching to a contrast theme, so switch to a SystemColors-based scheme and follow through the settings-change event; if you reference system colors, the UI follows the user's colors automatically
theme["Switch to a contrast theme"] --> qh{"How are colors specified?"}
qh -->|Hard-coded| broken["Color scheme breaks"]
qh -->|System color references| ok["Follows the user's colors automatically"]
broken -.-> fix["Switch to SystemColors"]
fix -.-> ev["Follow through the settings-change event"]
Figure 14: Only hard-coded colors break under a contrast theme; system color references follow automatically.
Include Surviving High DPI in the Same Check
Users with low vision often work with a high OS scaling factor (DPI scaling), so high-DPI support is also part of accessibility. An app whose layout breaks at 125% to 200% is unusable in that environment.
For specifics, see “High-DPI Support in WinForms” and “WPF High-DPI Support”.
8. Verification in Practice — Accessibility Insights and Hands-On Screen Reader Checks
8.1. Accessibility Insights for Windows
Microsoft’s Accessibility Insights for Windows offers three ways of working, depending on your goal.7
| Mode | What it checks | When to use it |
|---|---|---|
| Live Inspect | The UIA information (Name, ControlType, patterns, and so on) of the element under the mouse or with keyboard focus | The fastest way to find out “what is this button’s Name?” |
| FastPass | A lightweight check that detects high-impact problems in under five minutes. Finds problems that can be judged mechanically, such as a missing Name | Listing the problems on each new screen |
| Troubleshooting | Helps diagnose and fix a specific problem, and leads from a detected problem to the per-framework fix guide | Finding out how to fix a detected problem |
Inspect.exe and AccEvent, included in the Windows SDK, can also show the UIA tree and properties, but they are positioned as legacy tools, and moving to Accessibility Insights is now recommended.7
flowchart TB
accTitle: The three modes of Accessibility Insights
accDescr: Accessibility Insights for Windows provides Live Inspect for checking UIA properties, FastPass for a lightweight check of high-impact problems, and Troubleshooting for help with diagnosing and fixing problems, and migration from legacy tools such as Inspect.exe is recommended
ai["Accessibility Insights"] --> live["Live Inspect"]
ai --> fast["FastPass"]
ai --> ts["Troubleshooting"]
live --> livef["Check UIA properties"]
fast --> fastf["Detect high-impact problems"]
ts --> tsf["Help diagnose and fix"]
legacy["Inspect.exe and others"] -.->|Migration recommended| ai
Figure 15: Accessibility Insights has three modes, checking, detecting, and diagnosing, and is the recommended replacement for the legacy tools.
8.2. Hands-On Checks with a Screen Reader
Passing an automated check and being able to complete actual work are two different things. Tools can detect only problems that can be judged mechanically, so always finish by walking through a business operation with a screen reader.
First, start Narrator with Ctrl+Windows key+Enter, or install the free NVDA.10 Next, pick a representative task such as “enter one order and confirm it,” and try to complete it by announcements alone, without looking at the screen or with the display turned off.
Problems such as an incoherent announcement order despite names being set, or focus escaping outside a modal dialog, are found only through this kind of hands-on check.
flowchart TB
accTitle: Combining tool verification and hands-on checks
accDescr: An automated check such as FastPass can detect only problems that can be judged mechanically; for the rest, walk through actual business operations with a screen reader and find announcement-order and focus problems hands-on
tool["Automated tool check"] --> kikai["Problems that can be judged mechanically"]
tool -.-> nokori["Undetectable problems remain"]
nokori --> sr["Hands-on check with a screen reader"]
sr --> task["Walk through a business operation"]
task --> mieru["Announcement order and focus problems"]
Figure 16: Use the automated check to list the mechanical problems, and find the rest through hands-on checks with a screen reader.
8.3. Building It into the Development Flow, and the Synergy with UI Test Automation
To keep verification from depending on particular individuals, we recommend adding the following checklist to the review items for every new screen.
| # | Check item | Means |
|---|---|---|
| 1 | Zero errors in FastPass | Accessibility Insights |
| 2 | Every input field and button has a Name | Live Inspect |
| 3 | Every function is reachable with the Tab key alone | Manual |
| 4 | Enter/Esc and the main shortcuts work | Manual |
| 5 | Text contrast ratio of at least 4.5:1 | Contrast checker |
| 6 | Nothing breaks under a contrast theme | Switch the theme and inspect visually |
| 7 | Nothing breaks at 200% scaling | Change the display setting and inspect visually |
| 8 | A representative task can be completed with a screen reader | Narrator/NVDA |
Reuse the UIA Work for Automated Tests
UI test automation with FlaUI and similar tools is built on the same UIA that screen readers use. The Name and patterns you put in place for accessibility become building blocks for test code, and the AutomationId you designed for tests also makes debugging in Live Inspect easier.
Conversely, a UI that does not appear in the UIA tree is invisible to tests and to assistive technology alike. Accessibility and testability are two sides of the same investment. For details, see “UI Automated Testing for Windows Desktop Apps”.
flowchart TB
accTitle: The synergy between accessibility and UI test automation
accDescr: Screen readers and UI test automation such as FlaUI are built on the same UIA, so the Name and patterns you put in place can be used from both, and a UI that does not appear in the UIA tree is invisible to either
uia["UIA tree put in order"] --> sr["Screen readers can read it"]
uia --> test["UI test automation can use it"]
sr -.-> both["Two sides of the same investment"]
test -.-> both
hidden["UI absent from UIA"] -.-> invisible["Invisible to both"]
Figure 17: Because both sit on the same UIA foundation, putting the UIA tree in order helps assistive technology and UI test automation alike.
9. How to Prioritize — Do Not Fix Every Screen at Once
Overhauling a core system with hundreds of screens all at once is unrealistic in terms of both cost and quality. We recommend proceeding in the following three stages.
9.1. Start with the Screens That User Relies On at Work
Reasonable accommodation is a process of responding individually to the person’s request.2 First have the person operate their actual work with a screen reader, and identify together where they get stuck.
In most cases, the screens used in daily work narrow down to somewhere between a handful and a dozen or so. The critical problems among them, such as unnamed buttons or a confirm button that cannot be pressed from the keyboard, can be resolved with fixes measured in days.
9.2. Make New Development Compliant as Standard
Add the Chapter 8 checklist to the Definition of Done. The policy is that new screens are built compliant from the start. Unlike retrofitting, building it in at design time adds only a small cost.
9.3. Roll Out Across Screens by Fixing Shared Controls
Implement AccessibleName defaults and AutomationPeers in the in-house shared search dialogs, grids, date inputs, and so on. Fix a shared component, and the fix takes effect at once on every screen that uses it. It is a more cost-effective move than fixing individual screens one by one.
flowchart TB
accTitle: The three stages of prioritizing fixes
accDescr: Start with the screens the user relies on at work, make new development compliant as standard with the checklist, and roll out to every screen by fixing shared controls
s1["1. Start with the screens the user relies on"] --> s2["2. New development compliant as standard"] --> s3["3. Roll out through shared controls"]
s3 -.-> all["Takes effect at once on every screen using them"]
Figure 18: Rather than overhauling every screen at once, proceed in three stages: the screens in use, new development, and shared components.
9.4. Record the Course of the Dialogue, Not Just the Fixes
Just as important as the technical work is the record of the dialogue. Reasonable accommodation is a process of talking and adjusting case by case, not of fully meeting every request.
For fixes that would be an excessive burden, considering and agreeing on alternatives with the person, such as performing the task on a different screen, providing a CSV export, or covering it through operations, is a legitimate outcome of constructive dialogue.2
Recording what was requested, what was done, and what was offered as an alternative is what demonstrates the organization’s good faith.
flowchart TB
accTitle: The flow of constructive dialogue and records
accDescr: Respond to a request from a person with a disability through constructive dialogue, carry out the fixes that can be done, for fixes that would be an excessive burden consider and agree on an alternative with the person, and record what was requested, what was done, and what was offered as an alternative
req["Request"] --> talk["Constructive dialogue"]
talk --> q{"Excessive burden?"}
q -->|No| kaishu["Respond with a fix"]
q -->|Yes| alt["Consider and agree on an alternative"]
kaishu --> rec["Record the course of events"]
alt --> rec
Figure 19: In constructive dialogue, agree with the person on a fix or an alternative, and keep a record of how it went.
10. Summary
Separating the legal framework, the technology, and the process makes the starting point visible.
On the legal side, reasonable accommodation by businesses has been an obligation since April 2024, and by employers in the employment field since 2016. Fixing an app in advance counts as “environmental improvement” (a duty to make efforts), and the further it has gone, the lighter the individual response. Record the course of the dialogue as well.
On the technical side, inspect desktop apps around WCAG (JIS X 8341-3:2016) through WCAG2ICT. The foundation is the UIA tree, its properties (Name/ControlType/AutomationId), and the control patterns. Naming, the top priority, is handled with AccessibleName and Label plus tab order in WinForms, AutomationProperties.Name/LabeledBy in WPF, and an AutomationPeer for custom controls.
On top of that, put tab order, access keys, and focus indication in order so that every function can be reached from the keyboard alone. For color, use a 4.5:1 contrast ratio as the guideline, do not rely on color alone, and respect the system colors under contrast themes. These improvements also raise the productivity of every operator.
The process runs in the order screens the user relies on, compliant-as-standard new development, and rollout through shared controls. Combine FastPass and Live Inspect in Accessibility Insights with hands-on checks in Narrator/NVDA, and build them into the development flow as the checklist for new screens.
As a first step, we recommend picking one of your main screens, running FastPass in Accessibility Insights for Windows, and then walking through the work with the Tab key alone. In 30 minutes you will see, in surprisingly concrete terms, where your app currently stands.
Related Articles
- UI Automated Testing for Windows Desktop Apps — How UI Automation Works and Building Robust Tests with FlaUI
- Windows App UX Design - Priorities by Usage Environment
- High-DPI Support in WinForms — Why the UI Blurs or Breaks on 4K Monitors, and Practical Fixes
- WPF High-DPI Support — Why It Still Blurs and Bleeds Despite Being ‘Supposedly DPI-Aware,’ and How to Fix It
- Why KomuraSoft Builds Websites on the Digital Agency Design System — Low Cost and High Quality Can Coexist
- Japanese Font and Character Pitfalls — Handling JIS2004, IVS, and Gaiji in Business Apps
Related Consulting Areas
KomuraSoft LLC handles accessibility fixes for WinForms/WPF business apps (screen reader support, keyboard operation, contrast theme support), AutomationPeer implementation for shared controls, and current-state diagnosis and prioritization with Accessibility Insights. It is fine to start from the stage of “we want to check whether an employee can use our app with a screen reader.”
References
-
Microsoft Learn, UI Automation Specification. On UI Automation providing UI information to assistive technology such as screen readers and enabling operation by means other than standard input, and on the composition of UIA elements, the tree, properties, control patterns, control types, and events. ↩ ↩2 ↩3 ↩4
-
Cabinet Office, Leaflet: “The provision of reasonable accommodation became mandatory on April 1, 2024”. On the 2021 amendment to the Act for Eliminating Discrimination against Persons with Disabilities taking effect on April 1, 2024 and making the provision of reasonable accommodation by businesses mandatory; on reasonable accommodation being a response, within a range that is not an excessive burden, to an expression of wishes by a person with a disability; on the importance of constructive dialogue and on unilateral refusal potentially violating the obligation; on “environmental improvement,” advance measures for an unspecified number of persons with disabilities, being a duty to make efforts; and on employment and work being governed by the Act on Employment Promotion of Persons with Disabilities. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9
-
Ministry of Health, Labour and Welfare, Prohibition of discrimination against persons with disabilities and the obligation to provide reasonable accommodation in the field of employment. On the amended Act on Employment Promotion of Persons with Disabilities, in effect since April 2016, obligating employers to refrain from disability discrimination in employment and to provide reasonable accommodation within a range that is not an excessive burden, and on related materials such as the reasonable accommodation guidelines. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, WinForms: Setting the accessible name on a control. On Text being reused as the UIA Name for some controls but not for ComboBox, ListBox, ListView, PictureBox, ProgressBar, TabControl, TextBox, TreeView, and the like; on placing the target control directly after a Label’s TabIndex so that the Label’s text is used as the Name; and on setting AccessibleName explicitly and the problem of an empty string remaining in the designer file. ↩ ↩2 ↩3 ↩4
-
W3C / translated by the Web Accessibility Infrastructure Committee (WAIC), Web Content Accessibility Guidelines (WCAG) 2.1, Japanese translation. On success criterion 1.4.3 (Contrast (Minimum)) requiring 4.5:1 for text and 3:1 for large text, success criterion 1.4.1 (Use of Color) requiring that color not be the only visual means, and success criterion 2.1.1 (Keyboard) requiring that all functionality be operable from the keyboard. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Accessibility testing. On the three scenarios of Accessibility Insights for Windows, Live Inspect (checking UIA properties by hover or focus), FastPass (detecting high-impact problems in under five minutes), and Troubleshooting, and on the recommended migration from legacy tools such as Inspect and AccEvent. ↩ ↩2 ↩3
-
Web Accessibility Infrastructure Committee (WAIC), Understanding JIS X 8341-3:2016. On JIS X 8341-3:2016 being an identical standard of ISO/IEC 40500:2012 whose body has the same content as WCAG 2.0, and on the scope of web content the standard assumes. ↩ ↩2
-
W3C, Guidance on Applying WCAG 2 to Non-Web Information and Communications Technologies (WCAG2ICT). On the W3C Group Note that shows how to apply the principles, guidelines, and success criteria of WCAG 2.0/2.1/2.2 to non-web documents and software. ↩ ↩2 ↩3
-
NVDA Japanese Team, NVDA Japanese version. On NVDA, the free and open-source screen reader for Windows, and the availability of its Japanese version. ↩ ↩2
-
Microsoft Learn, Walkthrough: Creating an Accessible Windows-based Application. On placing a descriptive Label immediately before an input field in the tab order, access keys with & in Text, detecting high contrast with SystemInformation.HighContrast and using SystemColors, following the UserPreferenceChanged event, and adding visual cues to information conveyed by color. ↩ ↩2 ↩3
-
Microsoft Learn, Providing Accessibility Information for Controls. On the AccessibleName, AccessibleDescription, AccessibleRole, and AccessibleDefaultActionDescription properties of WinForms controls and how to set them. ↩
-
Microsoft Learn, WPF: Setting the accessible name on an edit field. On a TextBlock’s Text being reused as the UIA Name while a TextBox’s Text is exposed as the UIA Value, and on associating a label TextBlock with a TextBox through AutomationProperties.LabeledBy or setting AutomationProperties.Name. ↩ ↩2
-
Microsoft Learn, UI Automation of a WPF Custom Control. On a custom control overriding OnCreateAutomationPeer to return an AutomationPeer-derived class, inheriting the Peer class that corresponds to the base control, providing pattern providers through GetPattern, and overriding from XAML through AutomationProperties attributes. ↩ ↩2 ↩3
-
Microsoft Learn, Contrast themes. On contrast themes using a constrained palette with a contrast ratio of roughly 7:1 or more, selecting built-in themes and editing colors, and the SystemColor family of resources being defined as foreground/background pairs that follow theme switches automatically. ↩ ↩2
Related Articles
Recent articles sharing the same tags. Deepen your understanding with closely related topics.
Dark Mode and Contrast Themes in Windows Apps — DWM Dark Title Bars, System Theme Tracking in WinForms/WPF, and Drawing under High Contrast
How to make WinForms/WPF apps follow the dark mode and contrast themes of Windows 11. Covers DWM dark title bars, SetColorMode and ThemeM...
UI Automated Testing for Windows Desktop Apps — How UI Automation Works and Building Robust Tests with FlaUI
A practical guide to UI automated testing for WinForms/WPF apps, working from how Windows UI Automation itself works (the tree, Automatio...
Windows App Outsourcing and Custom Software Development: What to Sort Out Before You Ask
Before commissioning Windows app outsourcing or custom software development, here is how to sort out existing software modification, devi...
End of Servicing for Windows Printer Drivers — How Business Apps Should Prepare Their Report and Label Printing
Microsoft is phasing out v3/v4 printer drivers. What Windows protected print mode removes, and how to inventory and prepare report and la...
What "Not Responding" Really Is — How Windows Decides an App Has Hung, and How to Design Apps That Don't
Windows marks a window Not Responding after 5 seconds without message retrieval and shows a ghost window: the check, hang causes, UI-thre...
Related Topics
These topic pages place the article in a broader service and decision context.
Windows Technical Topics
Topic hub for KomuraSoft LLC's Windows development, investigation, and legacy-asset articles.
UI Threading & Timers
Topic page for WPF / WinForms UI threading, async flow, Dispatcher usage, and timer decisions.
Where This Topic Connects
This article connects naturally to the following service pages.
Windows App Development
We support Windows desktop applications that involve resident processing, device integration, operational logging, and maintainable structure.
Frequently Asked Questions
Common questions about the topic of this article.
- Is accessibility support for a business app now required by law?
- The 2021 amendment to the Act for Eliminating Discrimination against Persons with Disabilities took effect on April 1, 2024, and businesses too are now obligated to provide reasonable accommodation to persons with disabilities. Reasonable accommodation means removing an individual barrier, within a range that is not an excessive burden, when a person with a disability makes a request; fixing an app in advance so that it is easier to use is positioned as a duty to make efforts called environmental improvement. Note that the employment field, such as the relationship between an employee and the company, falls under the Act on Employment Promotion of Persons with Disabilities rather than the anti-discrimination act, and there the amendment that took effect in April 2016 obligates employers to provide reasonable accommodation. In other words, the situation where an employee cannot use a business app has been in the territory of obligation for some time. What to support and how far depends on the individual situation, so check the primary sources from the Cabinet Office and the Ministry of Health, Labour and Welfare, and decide through dialogue with the person concerned.
- How does a screen reader read a Windows desktop app?
- Screen readers such as Narrator and NVDA read an app's UI through an accessibility foundation called UI Automation (UIA). The app exposes the elements on screen in a structure called the UIA tree, and each element has properties such as Name (purpose) and ControlType (kind) plus control patterns such as Invoke (press) and Value (value). The screen reader announces this information as something like "Confirm order, button" and operates the element through the patterns. Standard WinForms and WPF controls come with this mechanism built in, so the developer's main jobs are to never leave Name empty, to make the UI operable from the keyboard, and to implement the information on custom controls.
- Where should we start with an existing WinForms app?
- The shortest path is to run FastPass in Accessibility Insights for Windows against the target screen and list the controls whose Name is empty and the tab-order problems. Start the fixes with setting AccessibleName on icon-only buttons, associating a Label by placing it immediately before the input field in the tab order, and tidying TabIndex so that it matches the visual order. Then start Narrator or NVDA and walk through an actual business operation without looking at the screen, and check where you get stuck. There is no need to fix every screen at once; it is realistic to start with the screens someone actually uses and to make new screens compliant as standard with a checklist.
- What do we need to do for high contrast (contrast themes)?
- The basic rule is to respect system colors rather than hard-coding colors. In WinForms, leave ForeColor/BackColor at their defaults or use SystemColors, detect the state with SystemInformation.HighContrast, and follow a switch through the UserPreferenceChanged event. In WPF and WinUI, too, the UI follows a theme switch automatically as long as it references the SystemColors family of resources. At the same time, stop conveying information by color alone, such as showing an error only in red, and add an icon or wording. Even under the normal theme, using WCAG's criterion of a text contrast ratio of at least 4.5:1 as a guide makes the UI easier to read on a poorly lit shop floor and for older users.
- Does accessibility work also help UI test automation?
- It does. UI test automation tools such as FlaUI are built on the same UI Automation that screen readers use. The Name, ControlType, and control patterns you put in place for accessibility can be used directly from test code, and an AutomationId designed for tests makes element identification stable. Conversely, a custom-drawn UI that does not appear in the UIA tree is invisible to screen readers and to tests alike. Accessibility and automated testing are investments in the same foundation, so putting either one in place lowers the cost of the other.