Доступность приложений Windows: UI Automation и разумное приспособление

· Обновлено: · · Доступность, UI Automation, Windows, WinForms, WPF, Разумное приспособление, Программы чтения с экрана, Закон об устранении дискриминации, Бизнес-приложения

История изменений (первая версия, опубликована 20 Aug 2026)
Первая публикация
Цитирование статьи(DOI (зарегистрированный архив): 10.5281/zenodo.22176499)

Приведённые ниже DOI относятся к ранее зарегистрированным архивным версиям, которые могут отличаться от текущего текста. Для ссылки на текущий текст используйте URL этой страницы.

Го Комура (2026). Доступность приложений Windows: UI Automation и разумное приспособление. KomuraSoft LLC. https://comcomponent.com/ru/blog/windows-app-accessibility-ui-automation-guide/

DOI (зарегистрированный архив)
10.5281/zenodo.22176499
DOI (последняя зарегистрированная версия)
10.5281/zenodo.22176500

«Сотрудник с нарушением зрения не может пользоваться нашей основной системой ввода заказов с программой чтения с экрана. Браузером и почтой пользуется без проблем, а в нашем бизнес-приложении объявления не работают.» Такие вопросы от ИТ-служб заказчиков слышим всё чаще.

Исходная точка решения — смотреть не на то, как выглядит экран, а на что вы сообщаете вспомогательным технологиям. В Windows есть UI Automation (UIA) — механизм, через который программы чтения с экрана читают сведения приложения. Когда понятно, как он работает, и закрыты основы имён, клавиатуры и цвета, пользоваться бизнес-приложением становится заметно проще.1

И юридически внутренние приложения Windows не исключение. Поправка 2021 года к Закону об устранении дискриминации в отношении инвалидов вступила в силу 1 апреля 2024 года: организации тоже обязаны предоставлять разумное приспособление. Сфера занятости, как в примере из начала, регулируется Законом о содействии трудоустройству инвалидов и является обязанностью работодателя с апреля 2016 года. Глава 2 разбирает это различие.23

По доступности настольных приложений Windows материалов меньше, чем по вебу, и волшебного решения «потом навесить» нет. Но большая часть нужных правок повышает производительность всех пользователей, с инвалидностью или без.

Статья рассчитана на разработчиков японских бизнес-приложений и сотрудников ИТ-служб. Она покрывает законодательную рамку и стандарты и устройство UIA, затем переходит к реализации в WinForms/WPF, работе с клавиатуры, цвету и контрасту, проверке и тому, как расставлять приоритеты исправлений.

Ход этой статьиСтруктура статьи, которая по порядку связывает законодательную рамку и стандарты, устройство UI Automation, реализацию в WinForms и WPF, работу с клавиатуры, цвет и контраст, инструменты проверки и то, как расставлять приоритетыЗаконодательная рамка и стандартыУстройство UI AutomationРеализация в WinForms/WPFРабота с клавиатурыЦвет и контрастИнструменты проверкиКак расставлять приоритеты

Рис. 1: Статья связывает законодательную рамку, механизм, реализацию, проверку и приоритеты в одну линию.

1. Сначала выводы

Три пункта, которые взять в первую очередь.

  1. Отделяйте индивидуальное разумное приспособление от предварительного обустройства среды. Разумное приспособление — процесс ответа на обращение через конструктивный диалог в пределах, не составляющих чрезмерное бремя. Для организаций это обязанность с апреля 2024 года, для работодателей в сфере занятости — с апреля 2016 года. Заранее доработать приложение относится к «обустройству среды» (обязанность прилагать усилия), что отличается от требования сделать каждый экран идеальным с самого начала.23
  2. Технический фундамент — публикация сведений в UIA плюс основы имён, клавиатуры и цвета. Name и ControlType дерева UIA и шаблоны вроде Invoke, Value и SelectionItem — материал для объявления и действий. Имена — в первую очередь. В WinForms это AccessibleName и связь Label с порядком табуляции, в WPF — AutomationProperties.Name/LabeledBy; плюс работа с клавиатуры, цветовая схема с ориентиром на коэффициент контрастности 4,5:1 и отображение, которое не опирается только на цвет.1456
  3. Проверяйте и чините, начиная с реальной работы. Совмещайте FastPass в Accessibility Insights с практическими проверками программой чтения с экрана и идите по экранам, на которые опирается пользователь, затем новым экранам, затем общим элементам управления — в этом порядке. Те же правки помогают и автоматическим UI-тестам вроде FlaUI, которые используют тот же фундамент UIA.7

Технические критерии можно организовать вокруг WCAG. JIS X 8341-3:2016 — идентичный стандарт с тем же содержанием, что WCAG 2.0, а WCAG2ICT даёт указания, как применять его к не-веб-ПО. Раздел 2.2 идёт в подробности.89

Если читать по цели, начинайте с главы ниже.

Проблема или цель Что проверять Глава
Хотите знать, что изменила «обязанность» Различия между разумным приспособлением, обустройством среды и сферой занятости Глава 2
Кнопки и поля ввода объявляются неверно Сведения UIA и именование в каждой платформе Главы 3–5
Хотите закончить работу без мыши Порядок табуляции, клавиши доступа, фокус Глава 6
Трудно пользоваться после смены цветов или масштаба Контраст, системные цвета, высокий DPI Глава 7
Хотите диагностировать существующее приложение и решить объём правок Автоматические проверки, практические проверки, приоритеты и записи диалога Главы 8–9

Одной фразой: поддержка доступности значит «публиковать правильные имена и операции в дереве UIA и держаться основ клавиатуры и цвета».

На схеме сплошная линия обозначает отношение, которое выполняется всегда, а пунктирная — условное отношение (условия указаны в пояснении к каждому отношению на странице сведений). Полный список отношений (всего 16, с доказательствами и степенью уверенности) и определения основных понятий собраны на странице сведений карты знаний (на японском). Данные: JSON-LD / Turtle

2. Законодательная рамка и стандарты — что изменила «обязанность»

2.1. Закон об устранении дискриминации в отношении инвалидов — с апреля 2024 года организации тоже обязаны предоставлять разумное приспособление

Этот раздел разделяет три вопроса: что стало обязанностью, куда относятся предварительные правки и какой закон действует в сфере занятости.

Разумное приспособление организациями сменилось с обязанности прилагать усилия на обязанность

Закон об устранении дискриминации в отношении инвалидов запрещает административным органам и организациям «несправедливое дискриминационное обращение» с инвалидами и требует «предоставлять разумное приспособление». Поправкой 2021 года (Рэйва 3) предоставление разумного приспособления организациями, до того обязанность прилагать усилия, стало обязанностью, и поправка вступила в силу 1 апреля 2024 года (Рэйва 6).2

Листовка Канцелярии Кабинета министров объясняет это как ответ в пределах, не составляющих чрезмерное бремя, когда человек с инвалидностью выражает желание снять барьер. Поскольку конкретности различаются по типу инвалидности, сцене и ситуации, важен «конструктивный диалог», в котором человек и организация проговаривают и вместе рассматривают варианты. Листовка прямо пишет, что односторонний отказ от диалога может составлять нарушение обязанности предоставлять приспособление.2

Считайте предварительные правки приложения «обустройством среды»

Иметь всё готовым заранее — не то, что стало обязанностью. Меры, принятые заранее для неопределённого круга инвалидов, например пересмотр руководств, обучение и безбарьерность помещений, называют «обустройством среды» и позиционируют как обязанность прилагать усилия.2

Заранее привести бизнес-приложение в состояние, которым может пользоваться программа чтения с экрана, можно считать усилием на этой стороне обустройства среды. Чем дальше зашло это улучшение, тем легче бремя предоставления индивидуального разумного приспособления.

Где задействованы сотрудники, смотрите Закон о содействии трудоустройству инвалидов

Занятость и работа регулируются Законом о содействии трудоустройству инвалидов, а не Законом об устранении дискриминации в отношении инвалидов. Листовка Канцелярии Кабинета министров тоже отмечает это различие.2

По Закону о содействии трудоустройству инвалидов поправка, вступившая в силу в апреле 2016 года (Хэйсэй 28), обязывает работодателей воздерживаться от дискриминации по инвалидности при трудоустройстве и предоставлять разумное приспособление в пределах, не составляющих чрезмерное бремя. Вопрос из начала, «сотрудник не может пользоваться бизнес-приложением», поэтому давно в зоне обязанности — задолго до 2024 года.3

Куда относятся разумное приспособление и обустройство средыОтношения общей организации и человека с инвалидностью регулирует Закон об устранении дискриминации в отношении инвалидов, и предоставление разумного приспособления ответом на индивидуальное обращение через конструктивный диалог — обязанность с апреля 2024 года; сфера занятости — обязанность работодателя с апреля 2016 года по Закону о содействии трудоустройству инвалидов; заранее доработать приложение относится к обустройству среды, обязанности прилагать усилияОрганизация и человек с инвалидностьюЗанятость и работаКакая сцена?Закон об устранении дискриминации в отношении инвалидовЗакон о содействии трудоустройству инвалидовОтвечать на индивидуальные обращения через конструктивный диалогПредоставление разумного приспособления (обязанность с апреля 2024 года)Предоставление разумного приспособления (обязанность с апреля 2016 года)Предварительные правки приложения = обустройство среды (обязанность прилагать усилия)

Рис. 2: Применимый закон зависит от сцены; разумное приспособление — обязанность, а предварительные правки относятся к обустройству среды, обязанности прилагать усилия.

Как конкретный случай трактуется в праве, зависит от ситуации. Эта статья не идёт в юридическое толкование; она исходит из того, что может сделать инженер, когда его просят ответить. Первичные источники — материалы Канцелярии Кабинета министров и Министерства здравоохранения, труда и благосостояния.23

2.2. JIS X 8341-3 и WCAG — «критерии веба» распространяются и на ПО

Когда читаете технические стандарты подробно, организовать их вокруг WCAG даёт самую ясную картину. JIS X 8341-3:2016, WCAG и WCAG2ICT связаны так.869

Стандарт или документ Позиция Как эта статья его использует
JIS X 8341-3:2016 Идентичный стандарт ISO/IEC 40500:2012; тело стандарта имеет то же содержание, что WCAG 2.0 Схватить технические критерии доступности
WCAG Документ, который определяет критерии успеха. Расширен с 2.0 до 2.1/2.2, с японским переводом WAIC Конкретно проверить, что нужно сделать
WCAG2ICT Group Note W3C о применении WCAG 2.0/2.1/2.2 к не-веб-документам и ПО Применить ту же мысль к настольному приложению

На вопрос «разве WCAG не стандарт для веб-контента?» мост — WCAG2ICT. Полное название — Guidance on Applying WCAG 2 to Non-Web Information and Communications Technologies.9

Идеи вроде текстовых альтернатив, контраста, работы с клавиатуры и того, чтобы не передавать информацию одним цветом, применяются к настольному приложению Windows в той же рамке. С главы 3 эта статья превращает их в реализацию WinForms/WPF.

Связь JIS X 8341-3 и WCAGJIS X 8341-3:2016 — идентичный стандарт с тем же содержанием, что WCAG 2.0, а WCAG2ICT показывает, как применять критерии успеха WCAG к не-веб-ПО, поэтому настольное приложение Windows можно проверять в той же рамкеИдентичный стандарт с тем же содержаниемWCAG 2.0 (W3C)JIS X 8341-3:2016WCAG2ICTПрименено к не-веб-ПОНастольные приложения Windows

Рис. 3: JIS X 8341-3:2016 — идентичный стандарт WCAG 2.0, а WCAG2ICT распространяет те же критерии на настольные приложения.

3. Как вспомогательные технологии читают приложение — тройка UI Automation

3.1. Дерево UIA, свойства и шаблоны элементов управления

UI Automation (UIA), встроенная в Windows, — платформа доступности, которая посредничает между приложением и вспомогательными технологиями. Приложение публикует сведения UI как «поставщик», а вспомогательная технология вроде программы чтения с экрана получает их как «клиент». Операции UI средствами, отличными от стандартного ввода, тоже возможны благодаря этому механизму.1

Начните с понимания как тройки: структура экрана, природа каждого элемента и доступные операции.1

Элемент Роль Типичные примеры
Дерево UIA Дерево с рабочим столом в корне, от окна к элементу управления. Вспомогательная технология обходит это дерево, чтобы понять UI Окно, панель, кнопка, поле редактирования
Свойства Значения, которые описывают природу каждого элемента Name (назначение), ControlType (тип), AutomationId (идентификатор), IsEnabled, IsKeyboardFocusable
Шаблоны элементов управления Словарь «доступных операций» по типу Invoke (нажать), Value (читать/писать значение), SelectionItem (выбрать), Toggle (вкл/выкл), ExpandCollapse (развернуть/свернуть)

Например, объявление «Подтвердить заказ, кнопка», когда кнопка получает фокус, — примерно сочетание Name и типа элемента управления. Когда пользователь выдаёт команду выполнить, вспомогательная технология нажимает кнопку через шаблон Invoke.

Иначе говоря, кнопка, нарисованная на экране, и кнопка, которую вспомогательная технология может прочитать и которой может действовать, — разные вещи. Если Name и шаблоны не опубликованы правильно, кнопки как бы нет, хотя она видна на экране.

Тройка UI AutomationПриложение как поставщик публикует свойства и шаблоны элементов управления каждого элемента в дереве UIA; программа чтения с экрана как клиент объявляет Name и ControlType и действует через шаблоны вроде InvokeОбъявляетДействуетПриложение (поставщик)Дерево UIAСвойства (Name, ControlType и т. д.)Шаблоны (Invoke, Value и т. д.)Программа чтения с экрана (клиент)

Рис. 4: Программа чтения с экрана использует свойства и шаблоны, которые приложение опубликовало в дереве UIA, для объявления и действий.

3.2. Программа чтения с экрана — клиент UIA

Основные программы чтения с экрана в Windows — встроенный Экранный диктор (Narrator), свободный с открытым исходным кодом NVDA10 и PC-Talker, коммерческий продукт, широко используемый в Японии.

У каждой свой стиль объявления, но основной путь чтения UI настольного приложения во всех случаях — UIA. Поэтому работа на стороне приложения сводится к публикации правильных сведений в UIA, а не к поддержке конкретной программы чтения с экрана.

Общий путь основных программ чтения с экранаЕсли приложение публикует правильные сведения в UIA, Экранный диктор, NVDA и PC-Talker все могут читать UI одним путём, поэтому работа на стороне приложения не нацелена на конкретную программу, а сводится к публикации сведений в UIAПубликует сведенияПриложениеUI Automation (UIA)Экранный дикторNVDAPC-TalkerРабота сводится к публикации в UIA

Рис. 5: Основные программы чтения с экрана все идут через UIA, поэтому работа приложения сводится к публикации сведений в UIA.

3.3. Как объявляется «кнопка с пустым Name»?

Допустим, на панели инструментов есть кнопка «Сохранить», которая показывает только иконку дискеты. Хотя назначение визуально ясно, если Name оставить пустым, программа чтения с экрана объявляет не больше чем «кнопка». Если соседние «Открыть» и «Печать» в том же состоянии, пользователь слышит только «кнопка, кнопка, кнопка» и не может их различить.

Кнопки без Name и изображения, объявляемые только как «Image», перечислены в руководствах Microsoft по исправлениям как типичные проблемы, которые останавливают работу пользователя.5

Стандартные элементы WinForms/WPF поддерживают UIA с самого начала, и у большинства Name выводится автоматически из текста или метки. Три типичных способа поломки такие.

Типичная причина Что проверять
Только иконка, без материала для имени Задано ли имя для объявления явно
Нет связи с меткой Связано ли поле ввода с отображаемой меткой
Собственная отрисовка, которая не публикует сведения Появляются ли осмысленные сведения в дереве UIA

Следующие две главы связывают эту сортировку с правками для WinForms и WPF соответственно.

Три типичных способа, которыми ломается объявлениеОбъявление ломается, когда нет материала для имени, потому что элемент только с иконкой, когда нет связи с меткой или когда собственная отрисовка не кладёт сведения в дерево UIA, и элемент в итоге объявляется только как кнопкаТолько иконка, нет материалаName оказывается пустымНет связи с меткойСобственная отрисовка ничего не публикуетОбъявляется только как кнопка

Рис. 6: Сломанные объявления обычно сводятся к трём шаблонам: нет материала для имени, нет связи или собственная отрисовка.

4. Реализация в WinForms — AccessibleName и порядок табуляции

4.1. Элементы, у которых Text становится Name автоматически, и элементы, у которых нет

Сначала проверьте, относится ли элемент к типу, у которого Text используется как имя

В WinForms даже среди элементов, которые показывают текст, одни используют Text как UIA Name, а другие нет.4

Примеры элементов Как обрабатывается Name
Button, CheckBox Значение свойства Text используется как Name
ComboBox, ListBox, ListView, PictureBox, ProgressBar, TabControl, TextBox, TreeView Text не становится Name, поэтому дайте имя другим средством

Используйте отображаемую метку и задавайте AccessibleName там, где метку поставить нельзя

Самый простой в сопровождении подход — поставить описательный Label непосредственно перед целевым элементом в порядке табуляции. Если TabIndex целевого элемента идёт сразу после TabIndex Label, текст Label используется как UIA Name. Отображение и объявление совпадают, и вы избегаете вести формулировку дважды.411

Там, где Label поставить нельзя, задайте AccessibleName явно. Можно также задать AccessibleDescription для дополнительной информации и AccessibleRole, когда роль должна совпадать с тем, что элемент на деле делает.12

Как решается имя элемента WinFormsДля Button и подобных Text становится UIA Name как есть; для элементов вроде TextBox, чей Text не переиспользуется, используется текст Label, поставленного непосредственно перед в порядке табуляции; где Label поставить нельзя, AccessibleName задают явноДаНетДаНетЭлементText становится Name?Text используется как Name как естьLabel непосредственно перед в порядке табуляции?Текст Label используется как NameЗадать AccessibleName явно

Рис. 7: Name в WinForms решается в порядке Text, Label непосредственно перед в порядке табуляции, затем AccessibleName.

// Кнопка панели только с иконкой: задать имя для объявления явно
saveToolStripButton.AccessibleName = "Сохранить";

// Кнопка только с изображением: имя плюс дополнительное описание
btnSearchCustomer.AccessibleName = "Поиск клиентов";
btnSearchCustomer.AccessibleDescription = "Ищет в справочнике клиентов по коду или имени";

// Поле ввода, где Label нельзя поставить непосредственно перед в порядке табуляции: задать напрямую
txtOrderNo.AccessibleName = "Номер заказа";

// PictureBox, переиспользованный как диаграмма: роль должна совпадать с тем, что это на деле
pictureBoxChart.AccessibleRole = AccessibleRole.Chart;
pictureBoxChart.AccessibleName = "Диаграмма числа заказов по месяцам";

Когда вы очистили имя, но объявление по умолчанию не возвращается

Если вы один раз задали AccessibleName в панели свойств Visual Studio, а затем очистили, в файле конструктора может остаться настройка с пустой строкой. Если эта настройка блокирует разрешение имени по умолчанию, удалите строку из файла конструктора.4

Проблема оставшегося AccessibleName с пустой строкойЕсли один раз задать AccessibleName в панели свойств, а затем очистить, в файле конструктора остаётся настройка с пустой строкой и блокирует разрешение имени по умолчанию, поэтому исправляют удалением строки из файла конструктораЗадать AccessibleNameОчистить в панели свойствОстаётся настройка с пустой строкойБлокирует разрешение имени по умолчаниюУдалить строку из файла конструктора

Рис. 8: Очистка значения в панели свойств оставляет пустую строку, поэтому исправляйте удалением строки из файла конструктора.

4.2. Частые правки на экране ввода заказов

Вот чек-лист мест, которые мы чаще всего чиним в бизнес-приложениях.

Частое состояние Проблема Правка
ToolStripButton только с иконкой Объявляется только как «кнопка» Задать AccessibleName
Label стоит рядом с TextBox, но порядок табуляции разбросан Имя поля ввода пустое или несвязанное Поставить поле ввода сразу после TabIndex Label
PictureBox используется как кнопка через Click Роль не передаётся как кнопка, и с клавиатуры нажать нельзя Заменить на Button или задать AccessibleRole/AccessibleName и добавить поддержку клавиатуры
Заголовки столбцов DataGridView пустые или только символы Смысл столбца теряется, когда объявляется ячейка Задать осмысленное имя столбца в HeaderText
Содержимое группирует только Panel, а заголовок — изображение Нельзя понять, какая это группа полей Использовать GroupBox или сделать заголовок Label

Каждая — правка на несколько строк, но для пользователя программы чтения с экрана это разница между экраном, которым нельзя пользоваться, и экраном, которым можно.

5. Реализация в WPF — AutomationProperties и AutomationPeer

5.1. AutomationProperties.Name / LabeledBy / HelpText

Дайте кнопке имя через строковый Content или явную настройку

У элемента, чей Content — строка, например у кнопки WPF, это содержимое используется как UIA Name. У кнопки, содержащей только Image или Path, напротив, нет материала для имени. Либо задайте явно через AutomationProperties.Name, либо, если рядом есть отображаемый текст, свяжите через AutomationProperties.LabeledBy.5

В TextBox отделяйте «имя» от «введённого значения»

Text у TextBlock переиспользуется как Name, но Text у TextBox публикуется в свойстве UIA Value и не становится Name. Даже когда поле держит значение, одно это не говорит пользователю, для чего поле.13

Для поля ввода первый выбор — связать отображаемый TextBlock через LabeledBy. Отображение и объявление совпадают, и вы избегаете вести формулировку дважды.13

<!-- Поле ввода: связать отображаемую метку через LabeledBy -->
<TextBlock x:Name="OrderNoLabel" Text="Номер заказа" />
<TextBox
    AutomationProperties.LabeledBy="{Binding ElementName=OrderNoLabel}"
    AutomationProperties.AutomationId="OrderNoTextBox" />

<!-- Кнопка только с иконкой: задать имя явно и добавить дополнение при необходимости -->
<Button
    AutomationProperties.Name="Подтвердить заказ"
    AutomationProperties.HelpText="Подтверждает вводимый заказ и резервирует запас">
    <Path Data="{StaticResource CheckIconGeometry}" Width="16" Height="16" />
</Button>
Как решается имя элемента WPFЭлемент, чей Content — строка, использует это содержимое как Name; иначе первый выбор — связать ближайшую отображаемую метку через LabeledBy, а если её нет, AutomationProperties.Name задают явно; Text у TextBox публикуется как Value, не как NameДаНетДаНетЭлементContent — строка?Содержимое становится NameРядом отображаемая метка?Связать через LabeledByЗадать Name явноText у TextBoxПубликуется как Value, не как Name

Рис. 9: Name в WPF решается в порядке строковый Content, LabeledBy, затем явная настройка; Text у TextBox не становится Name.

HelpText и AutomationId играют роли, отличные от имени

Дополнительная информация, которая не помещается в Name, публикуется через AutomationProperties.HelpText.5 AutomationId — идентификатор, который также используют, чтобы находить элементы в автоматических UI-тестах. Решение о соглашении именования на этапе проектирования экрана окупается в последующих тестах.

Коротко: Name — назначение, HelpText — дополнение, AutomationId — идентификатор. Как они используются в автоматических тестах, подробно разобрано в «UI-автотестах десктопных приложений Windows».

5.2. Собственным элементам нужен AutomationPeer

Элемент с собственной отрисовкой сам по себе не может публиковать осмысленные сведения в дереве UIA. В WPF вы публикуете имя, тип и шаблоны, переопределяя OnCreateAutomationPeer в классе, производном от UIElement, и возвращая класс, производный от AutomationPeer.14

Если наследуете существующий элемент, наследуйте и соответствующий Peer. Для ButtonBase, например, использование ButtonBaseAutomationPeer позволяет перенести уже реализованное поведение.14

Как AutomationPeer публикует сведенияСобственный элемент публикует имя, тип и шаблоны, переопределяя OnCreateAutomationPeer и возвращая класс, производный от AutomationPeer; если наследует существующий элемент, наследует соответствующий Peer и переносит уже реализованное поведениеСобственный элементOnCreateAutomationPeerВернуть класс, производный от PeerОпубликовать имя, тип и шаблоныНаследует существующий элементНаследовать соответствующий PeerПеренести реализованное поведение

Рис. 10: Собственный элемент возвращает Peer из OnCreateAutomationPeer, чтобы опубликовать сведения в UIA.

// Пример элемента, который сам рисует состояние линии как цветную лампу
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 ? "Состояние линии: онлайн" : "Состояние линии: офлайн";

    private static void OnIsOnlineChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // Поднять событие смены свойства UIA в момент смены значения. Без него
        // программа чтения с экрана держит старое имя и никогда не замечает смену состояния
        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 подходит для отображения состояния без операций

    protected override string GetNameCore()
        => StatusLamp.NameFor(((StatusLamp)Owner).IsOnline);
}

Уведомляйте о смене состояния, а не только о текущем имени

Пример выше совмещает две вещи: возврат имени, которое отражает текущее состояние, и подъём события смены свойства Name, когда меняется IsOnline.

Работа Peer — не только вернуть имя, но и сигнализировать о смене событием в тот момент, когда она происходит. У вспомогательной технологии нет собственного момента, чтобы заново запросить значение, поэтому без события реализация «правильна только когда спросят снова», и пользователи программы чтения с экрана никогда не узнают, что состояние изменилось.

Как смена состояния доходит до программы чтения с экранаВ момент смены значения элемента AutomationPeer поднимает событие смены свойства Name; вспомогательная технология не запрашивает заново сама, поэтому без события держит старое имя и никогда не замечает сменуПрограмма чтения с экранаAutomationPeerЭлементПрограмма чтения с экранаAutomationPeerЭлементБез события остаётся старое имяЗначение IsOnline меняетсяПоднимает событие смены свойства NameОбъявляет новое состояние

Рис. 11: Смена значения доходит до программы чтения с экрана только когда AutomationPeer сигнализирует её событием смены.

Если у элемента есть операции, реализуйте шаблоны и кладите их в общие компоненты

Для собственных элементов, которые можно нажать, у которых есть изменяемое значение или которые можно выбрать, переопределите GetPattern и предоставьте интерфейсы шаблонов вроде IInvokeProvider и IRangeValueProvider.14

Если встроить Peer в общую библиотеку элементов, каждый экран, который ею пользуется, становится соответствующим автоматически. Это фундамент для развёртывания, описанного в главе 9.

6. Можно ли дойти до каждой функции только с клавиатуры?

Критерий успеха WCAG 2.1.1 (Клавиатура) требует, чтобы вся функциональность была доступна через клавиатурный интерфейс.6 Пользователи программ чтения с экрана как правило не используют мышь, поэтому функция, до которой нельзя дойти с клавиатуры, — то же, что функция, которой нет.

6.1. Проверяйте перемещение, выполнение и текущую позицию

Проверяйте не только порядок табуляции, но и то, что основные операции можно выполнить и что текущий фокус виден.

Аспект Что проверять Основные средства в WinForms / WPF
Порядок табуляции Движется ли Tab в том же порядке, что визуальная раскладка (слева сверху вниз направо)? Навести TabIndex, задать TabStop
Клавиши доступа Можно ли Alt плюс буква прыгнуть напрямую к основным пунктам? & в Text для WinForms, _ в заголовке для WPF
Сочетания клавиш Есть ли у частых операций (сохранить, поиск, подтвердить) отдельная клавиша? Назначить Ctrl+S и подобные и показать их в меню
Индикация фокуса Видно ли, где фокус сейчас? Не убирать прямоугольник фокуса; рисовать его самим при собственной отрисовке
Функции только мышью Есть ли функция, доступная только двойным щелчком, правым щелчком, перетаскиванием или наведением? Предложить ту же функцию через меню или клавишу тоже
Диалоги Работают ли Enter = кнопка по умолчанию и Esc = отмена? AcceptButton/CancelButton, IsDefault/IsCancel

Пошаговое руководство по доступности WinForms также перечисляет как основы постановку метки непосредственно перед полем ввода в порядке табуляции и клавиши доступа у элементов и меню, к которым пользователь хочет перейти.11

6.2. Работа с клавиатуры повышает эффективность ввода для всех пользователей

Это не просто «дополнительная стоимость поддержки людей с инвалидностью». В штатной работе вроде ввода заказов может ли оператор закончить ввод, не уходя с домашней позиции, решает, сколько операций он проведёт.

Перепутанный порядок табуляции или операция, которая требует мыши, — дефект, который каждый день чуть срезает производительность каждого пользователя. Работа над доступностью и эффективность клавиатуры — два имени одной работы. О приоритетах по среде использования см. также «UX Windows-приложений».

Двойной эффект работы с клавиатурыНаведение порядка табуляции, клавиш доступа и индикации фокуса даёт сразу два эффекта: пользователи вспомогательных технологий могут дойти до функций и скорость ввода каждого оператора, а функция, доступная только мышью, — то же, что функция, которой нетРабота с клавиатуры приведена в порядокПользователи вспомогательных технологий могут работатьСкорость ввода каждого оператораФункции только мышьюТо же, что несуществующие функции

Рис. 12: Работа с клавиатуры даёт поддержку вспомогательных технологий и эффективность для всех пользователей сразу; функция только мышью — как несуществующая.

7. Цвет и контраст — 4,5:1 и «не только цветом»

7.1. Ориентир коэффициента контрастности — 4,5:1

Критерий успеха WCAG 1.4.3 (Контраст (минимум)) требует коэффициент контрастности не ниже 4,5:1 для текста и изображений текста и не ниже 3:1 для крупного текста.6

Макеты, которые кладут светло-серый текст на белый фон, не дотягивают до этого критерия чаще, чем можно подумать. Держите в уме людей, чьё зрение и цветовосприятие изменились с возрастом, и людей, которые работают в плохо освещённых местах вроде цехов, и сделайте привычкой измерять чекером контраста на ревью макета.

7.2. Не передавайте информацию одним цветом

Критерий успеха 1.4.1 (Использование цвета) говорит, что цвет не должен быть единственным визуальным средством передачи информации.6 Типичные случаи в бизнес-приложениях такие.

Передано только цветом Дополнительное средство
Строки ошибок показаны только красным текстом Иконка ошибки и столбец сообщения
Обязательные поля показаны только цветом метки Звёздочка или слово «Обязательно»
Состояние показано только цветом лампы Цвет плюс форма или текст вроде «Работает» и «Остановлено»

С учётом разнообразия цветовосприятия это тоже основа проектирования отображения, а не «особая мера».

Замена информации, переданной только цветомОтображение, которое показывает ошибки только красным текстом, заменяется иконкой ошибки и столбцом сообщения рядом, отображение обязательных полей только цветом метки получает маркер «Обязательно», а отображение состояния только цветом лампы заменяется формой или текстом рядом с цветомОшибки только красным текстомДобавить иконку и формулировкуОбязательность только цветом меткиДобавить маркер «Обязательно»Состояние только цветом лампыСовместить цвет с формой или текстом

Рис. 13: Замените типичные подсказки только цветом иконкой, маркером или формой и текстом рядом с цветом.

7.3. Следование темам контрастности (высокой контрастности)

Темы контрастности Windows (ранее высокая контрастность) — цветовые схемы, которые сильно разделяют передний план и фон. Встроенные темы рассчитаны на коэффициент контрастности примерно 7:1 и выше, и пользователи могут их выбирать и править.15

На стороне приложения не задавайте цвета жёстко; уважайте системные цвета. Что делать в каждой платформе — так.

Платформа Базовая цветовая схема Что проверять, когда есть собственные цвета
WinForms Оставляйте ForeColor/BackColor по умолчанию, чтобы использовались цветовые настройки пользователя Определяйте SystemInformation.HighContrast и переключайтесь на схему на базе SystemColors, затем следуйте сменам настроек через UserPreferenceChanged
WPF/WinUI Ссылайтесь на ресурсы семейства SystemColors, чтобы следовать сменам темы Проверьте, не области ли, залитые собственными кистями, ломают макет

Конкретные настройки WinForms — в пошаговом руководстве Microsoft, цвета тем — в документации тем контрастности.1115

Следование темам контрастностиМеста, где цвета заданы жёстко, ломаются при переключении на тему контрастности, поэтому переключайтесь на схему на базе SystemColors и следуйте через событие смены настроек; если ссылаетесь на системные цвета, UI следует цветам пользователя автоматическиЖёсткоСсылки на системные цветаПереключиться на тему контрастностиКак заданы цвета?Цветовая схема ломаетсяАвтоматически следует цветам пользователяПереключиться на SystemColorsСледовать через событие смены настроек

Рис. 14: Только жёстко заданные цвета ломаются в теме контрастности; ссылки на системные цвета следуют автоматически.

Включите выживание при высоком DPI в ту же проверку

Пользователи со слабым зрением часто работают с высоким коэффициентом масштаба ОС (масштабирование DPI), поэтому поддержка высокого DPI тоже часть доступности. Приложение, чей макет ломается при 125–200%, в этой среде непригодно.

Конкретику см. в «Поддержке высокого DPI в WinForms» и «Высоком DPI в WPF».

8. Практика проверки — Accessibility Insights и практические проверки программой чтения с экрана

8.1. Accessibility Insights for Windows

Accessibility Insights for Windows от Microsoft предлагает три способа работы в зависимости от цели.7

Режим Что проверяет Когда использовать
Live Inspect Сведения UIA (Name, ControlType, шаблоны и т. д.) элемента под мышью или с клавиатурным фокусом Самый быстрый способ узнать «какой Name у этой кнопки?»
FastPass Лёгкая проверка, которая за менее чем пять минут находит проблемы с высоким влиянием. Находит проблемы, которые можно судить механически, например отсутствующий Name Перечисление проблем на каждом новом экране
Troubleshooting Помогает диагностировать и чинить конкретную проблему и ведёт от обнаруженной проблемы к руководству по правке для платформы Узнать, как чинить обнаруженную проблему

Inspect.exe и AccEvent, входящие в Windows SDK, тоже могут показывать дерево UIA и свойства, но позиционируются как устаревшие инструменты, и сейчас рекомендуется переход на Accessibility Insights.7

Три режима Accessibility InsightsAccessibility Insights for Windows даёт Live Inspect для проверки свойств UIA, FastPass для лёгкой проверки проблем с высоким влиянием и Troubleshooting для помощи в диагностике и правке, и рекомендуется переход с устаревших инструментов вроде Inspect.exeРекомендуется переходAccessibility InsightsLive InspectFastPassTroubleshootingПроверить свойства UIAОбнаружить проблемы с высоким влияниемПомочь диагностировать и чинитьInspect.exe и другие

Рис. 15: У Accessibility Insights три режима — проверка, обнаружение и диагностика — и это рекомендуемая замена устаревшим инструментам.

8.2. Практические проверки программой чтения с экрана

Пройти автоматическую проверку и суметь закончить реальную работу — разные вещи. Инструменты могут обнаружить только проблемы, которые можно судить механически, поэтому всегда заканчивайте проходом рабочей операции с программой чтения с экрана.

Сначала запустите Экранный диктор сочетанием Ctrl+клавиша Windows+Enter или установите свободный NVDA.10 Затем выберите представительную задачу вроде «ввести один заказ и подтвердить» и попробуйте закончить её только по объявлениям, не глядя на экран или с выключенным дисплеем.

Проблемы вроде бессвязного порядка объявлений при заданных именах или фокуса, уходящего за модальный диалог, находятся только через такую практическую проверку.

Совмещение проверки инструментом и практических проверокАвтоматическая проверка вроде FastPass может обнаружить только проблемы, которые можно судить механически; остальное проходите реальными рабочими операциями с программой чтения с экрана и находите проблемы порядка объявлений и фокуса на практикеАвтоматическая проверка инструментомПроблемы, которые можно судить механическиОстаются необнаруживаемые проблемыПрактическая проверка программой чтения с экранаПройти рабочую операциюПроблемы порядка объявлений и фокуса

Рис. 16: Автоматической проверкой перечислите механические проблемы, остальное найдите практическими проверками программой чтения с экрана.

8.3. Встраивание в поток разработки и синергия с автоматическими UI-тестами

Чтобы проверка не зависела от конкретных людей, рекомендуем добавить следующий чек-лист в пункты ревью каждого нового экрана.

# Пункт проверки Средство
1 Ноль ошибок в FastPass Accessibility Insights
2 У каждого поля ввода и кнопки есть Name Live Inspect
3 До каждой функции можно дойти только клавишей Tab Вручную
4 Enter/Esc и основные сочетания работают Вручную
5 Коэффициент контрастности текста не ниже 4,5:1 Чекер контраста
6 Ничего не ломается в теме контрастности Переключить тему и осмотреть визуально
7 Ничего не ломается при масштабе 200% Сменить настройку дисплея и осмотреть визуально
8 Представительную задачу можно закончить с программой чтения с экрана Экранный диктор/NVDA

Переиспользуйте работу UIA для автоматических тестов

Автоматические UI-тесты с FlaUI и подобными построены на той же UIA, что и программы чтения с экрана. Name и шаблоны, которые вы готовите ради доступности, становятся строительными блоками тестового кода, а AutomationId, заложенный для тестов, также облегчает отладку в Live Inspect.

Наоборот, UI, который не появляется в дереве UIA, невидим и тестам, и вспомогательным технологиям. Доступность и тестируемость — две стороны одного вложения. Подробности — в «UI-автотестах десктопных приложений Windows».

Синергия доступности и автоматических UI-тестовПрограммы чтения с экрана и автоматические UI-тесты вроде FlaUI построены на той же UIA, поэтому Name и шаблоны, которые вы готовите, можно использовать с обеих сторон, а UI, которого нет в дереве UIA, невидим ни тем ни другимДерево UIA приведено в порядокПрограммы чтения с экрана могут читатьАвтоматические UI-тесты могут использоватьДве стороны одного вложенияUI отсутствует в UIAНевидим обоим

Рис. 17: Поскольку оба сидят на одном фундаменте UIA, наведение порядка в дереве UIA помогает вспомогательным технологиям и автоматическим UI-тестам.

9. Как расставлять приоритеты — не чините все экраны сразу

Перелопатить основную систему с сотнями экранов разом нереально и по стоимости, и по качеству. Рекомендуем идти в три следующих этапа.

9.1. Начните с экранов, на которые этот пользователь опирается в работе

Разумное приспособление — процесс индивидуального ответа на обращение человека.2 Сначала пусть человек пройдёт реальную работу с программой чтения с экрана, и вместе найдите, где он застревает.

В большинстве случаев экраны ежедневной работы сужаются до нескольких или десятка с небольшим. Критические проблемы среди них, например безымянные кнопки или кнопка подтверждения, которую нельзя нажать с клавиатуры, можно закрыть правками, измеряемыми днями.

9.2. Делайте новую разработку соответствующей как стандарт

Добавьте чек-лист главы 8 в Definition of Done. Политика — новые экраны сразу строят соответствующими. В отличие от донастройки, закладывание на этапе проектирования добавляет лишь небольшую стоимость.

9.3. Разверните по экранам, чиня общие элементы управления

Реализуйте значения AccessibleName по умолчанию и AutomationPeer в общих внутрифирменных диалогах поиска, сетках, вводе дат и т. п. Почините общий компонент — и правка сразу действует на каждом экране, который им пользуется. Это более выгодный ход, чем чинить отдельные экраны по одному.

Три этапа расстановки приоритетов правокНачните с экранов, на которые пользователь опирается в работе, делайте новую разработку соответствующей как стандарт с чек-листом и разверните на каждый экран, чиня общие элементы управления1. Начать с экранов, на которые опирается пользователь2. Новая разработка соответствующая как стандарт3. Развернуть через общие элементыСразу действует на каждом экране, который ими пользуется

Рис. 18: Вместо того чтобы перелопатить все экраны разом, идите в три этапа: экраны в использовании, новая разработка и общие компоненты.

9.4. Записывайте ход диалога, а не только правки

Не менее важна, чем техническая работа, запись диалога. Разумное приспособление — процесс разговора и настройки от случая к случаю, а не полного удовлетворения каждого запроса.

Для правок, которые были бы чрезмерным бременем, рассмотрение и согласование с человеком альтернатив вроде выполнения задачи на другом экране, предоставления экспорта CSV или покрытия через операции — законный исход конструктивного диалога.2

Запись что запросили, что сделали и что предложили как альтернативу — то, что демонстрирует добросовестность организации.

Поток конструктивного диалога и записейОтветить на обращение человека с инвалидностью через конструктивный диалог, выполнить правки, которые можно сделать, для правок, которые были бы чрезмерным бременем, рассмотреть и согласовать с человеком альтернативу и записать, что запросили, что сделали и что предложили как альтернативуНетДаОбращениеКонструктивный диалогЧрезмерное бремя?Ответить правкойРассмотреть и согласовать альтернативуЗаписать ход событий

Рис. 19: В конструктивном диалоге согласуйте с человеком правку или альтернативу и ведите запись того, как это шло.

10. Итог

Разделение законодательной рамки, технологии и процесса делает исходную точку видимой.

На юридической стороне разумное приспособление организациями — обязанность с апреля 2024 года, работодателями в сфере занятости — с 2016 года. Заранее доработать приложение относится к «обустройству среды» (обязанность прилагать усилия), и чем дальше оно зашло, тем легче индивидуальный ответ. Записывайте и ход диалога.

На технической стороне проверяйте настольные приложения вокруг WCAG (JIS X 8341-3:2016) через WCAG2ICT. Фундамент — дерево UIA, его свойства (Name/ControlType/AutomationId) и шаблоны элементов управления. Именование, первый приоритет, в WinForms ведут AccessibleName и Label плюс порядок табуляции, в WPF — AutomationProperties.Name/LabeledBy, для собственных элементов — AutomationPeer.

Поверх этого наведите порядок табуляции, клавиши доступа и индикацию фокуса, чтобы до каждой функции можно было дойти только с клавиатуры. Для цвета используйте коэффициент контрастности 4,5:1 как ориентир, не опирайтесь только на цвет и уважайте системные цвета в темах контрастности. Эти правки также повышают производительность каждого оператора.

Процесс идёт в порядке экраны, на которые опирается пользователь, новая разработка соответствующая как стандарт и развёртывание через общие элементы. Совмещайте FastPass и Live Inspect в Accessibility Insights с практическими проверками в Экранном дикторе/NVDA и встраивайте их в поток разработки как чек-лист новых экранов.

Как первый шаг рекомендуем взять один из основных экранов, прогнать FastPass в Accessibility Insights for Windows, а затем пройти работу только клавишей Tab. За 30 минут вы увидите на удивление конкретно, где сейчас стоит ваше приложение.

Похожие статьи

Смежные области консультирования

KomuraSoft LLC занимается правками доступности бизнес-приложений WinForms/WPF (поддержка программ чтения с экрана, работа с клавиатуры, поддержка тем контрастности), реализацией AutomationPeer для общих элементов управления и диагностикой текущего состояния и расстановкой приоритетов через Accessibility Insights. Можно начать со стадии «хотим проверить, может ли сотрудник пользоваться нашим приложением с программой чтения с экрана».

Справочные ссылки

  1. Microsoft Learn, UI Automation Specification. О том, что UI Automation даёт сведения UI вспомогательным технологиям вроде программ чтения с экрана и позволяет действовать средствами, отличными от стандартного ввода, и о составе элементов UIA, дерева, свойств, шаблонов элементов управления, типов элементов управления и событий. ↩ ↩2 ↩3 ↩4

  2. Канцелярия Кабинета министров, Листовка: «Предоставление разумного приспособления стало обязательным с 1 апреля 2024 года». О том, что поправка 2021 года к Закону об устранении дискриминации в отношении инвалидов вступила в силу 1 апреля 2024 года и сделала предоставление разумного приспособления организациями обязательным; о том, что разумное приспособление — ответ в пределах, не составляющих чрезмерное бремя, на выражение желания человеком с инвалидностью; о важности конструктивного диалога и о том, что односторонний отказ может нарушать обязанность; о том, что «обустройство среды», предварительные меры для неопределённого круга инвалидов, — обязанность прилагать усилия; и о том, что занятость и работа регулируются Законом о содействии трудоустройству инвалидов. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9

  3. Министерство здравоохранения, труда и благосостояния, Запрет дискриминации инвалидов и обязанность предоставлять разумное приспособление в сфере занятости. О том, что изменённый Закон о содействии трудоустройству инвалидов, действующий с апреля 2016 года, обязывает работодателей воздерживаться от дискриминации по инвалидности при трудоустройстве и предоставлять разумное приспособление в пределах, не составляющих чрезмерное бремя, и о связанных материалах вроде руководств по разумному приспособлению. ↩ ↩2 ↩3 ↩4

  4. Microsoft Learn, WinForms: Setting the accessible name on a control. О том, что Text переиспользуется как UIA Name для некоторых элементов, но не для ComboBox, ListBox, ListView, PictureBox, ProgressBar, TabControl, TextBox, TreeView и подобных; о постановке целевого элемента сразу после TabIndex Label, чтобы текст Label использовался как Name; и о явном задании AccessibleName и проблеме оставшейся пустой строки в файле конструктора. ↩ ↩2 ↩3 ↩4

  5. Microsoft Learn, WPF: Setting the accessible name on a button. О том, что Content кнопки по умолчанию переиспользуется как UIA Name, о том, что программы чтения с экрана не могут объявить назначение безымянной кнопки, и о связи TextBlock через AutomationProperties.LabeledBy и явном задании AutomationProperties.Name. ↩ ↩2 ↩3 ↩4

  6. W3C / перевод Web Accessibility Infrastructure Committee (WAIC), Web Content Accessibility Guidelines (WCAG) 2.1, японский перевод. О том, что критерий успеха 1.4.3 (Контраст (минимум)) требует 4,5:1 для текста и 3:1 для крупного текста, критерий успеха 1.4.1 (Использование цвета) требует, чтобы цвет не был единственным визуальным средством, и критерий успеха 2.1.1 (Клавиатура) требует, чтобы вся функциональность была доступна с клавиатуры. ↩ ↩2 ↩3 ↩4 ↩5

  7. Microsoft Learn, Accessibility testing. О трёх сценариях Accessibility Insights for Windows: Live Inspect (проверка свойств UIA наведением или фокусом), FastPass (обнаружение проблем с высоким влиянием менее чем за пять минут) и Troubleshooting, и о рекомендуемом переходе с устаревших инструментов вроде Inspect и AccEvent. ↩ ↩2 ↩3

  8. Web Accessibility Infrastructure Committee (WAIC), Understanding JIS X 8341-3:2016. О том, что JIS X 8341-3:2016 — идентичный стандарт ISO/IEC 40500:2012, чьё тело имеет то же содержание, что WCAG 2.0, и об области веб-контента, которую предполагает стандарт. ↩ ↩2

  9. W3C, Guidance on Applying WCAG 2 to Non-Web Information and Communications Technologies (WCAG2ICT). О Group Note W3C, которая показывает, как применять принципы, руководства и критерии успеха WCAG 2.0/2.1/2.2 к не-веб-документам и ПО. ↩ ↩2 ↩3

  10. NVDA Japanese Team, NVDA Japanese version. О NVDA, свободной программе чтения с экрана для Windows с открытым исходным кодом, и о наличии её японской версии. ↩ ↩2

  11. Microsoft Learn, Walkthrough: Creating an Accessible Windows-based Application. О постановке описательного Label непосредственно перед полем ввода в порядке табуляции, клавишах доступа через & в Text, определении высокой контрастности через SystemInformation.HighContrast и использовании SystemColors, следовании событию UserPreferenceChanged и добавлении визуальных подсказок к информации, переданной цветом. ↩ ↩2 ↩3

  12. Microsoft Learn, Providing Accessibility Information for Controls. О свойствах AccessibleName, AccessibleDescription, AccessibleRole и AccessibleDefaultActionDescription элементов WinForms и о том, как их задавать. ↩

  13. Microsoft Learn, WPF: Setting the accessible name on an edit field. О том, что Text у TextBlock переиспользуется как UIA Name, а Text у TextBox публикуется как UIA Value, и о связи метки TextBlock с TextBox через AutomationProperties.LabeledBy или задании AutomationProperties.Name. ↩ ↩2

  14. Microsoft Learn, UI Automation of a WPF Custom Control. О том, что собственный элемент переопределяет OnCreateAutomationPeer, чтобы вернуть класс, производный от AutomationPeer, наследует класс Peer, соответствующий базовому элементу, предоставляет поставщиков шаблонов через GetPattern и переопределяет из XAML через атрибуты AutomationProperties. ↩ ↩2 ↩3

  15. Microsoft Learn, Contrast themes. О том, что темы контрастности используют ограниченную палитру с коэффициентом контрастности примерно 7:1 и выше, выборе встроенных тем и правке цветов и о том, что семейство ресурсов SystemColor определено как пары передний план/фон, которые автоматически следуют сменам темы. ↩ ↩2

Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.

Тёмный режим и темы контрастности в приложениях Windows ── тёмная панель заголовка DWM, следование системной теме в WinForms/WPF, отрисовка при высокой контрастности

Как заставить приложения WinForms и WPF следовать тёмному режиму и темам контрастности Windows 11. Тёмная панель заголовка DWM, SetColorM...

Эти страницы показывают тему статьи в более широком контексте услуг и решений.

Статья напрямую связана со следующими услугами.

Частые вопросы

Вопросы, которые часто возникают при консультациях по теме статьи.

Обязана ли организация по закону делать бизнес-приложение доступным?
Поправка 2021 года к Закону Японии об устранении дискриминации в отношении инвалидов вступила в силу 1 апреля 2024 года: организации тоже обязаны предоставлять инвалидам разумное приспособление. Разумное приспособление — это ответ на обращение человека с инвалидностью: снять конкретный барьер в пределах, не составляющих чрезмерное бремя. Заранее сделать приложение удобнее относится к обустройству среды — обязанности прилагать усилия, а не к жёсткому требованию. Отношения сотрудника и работодателя регулирует не этот закон, а Закон о содействии трудоустройству инвалидов: там обязанность разумного приспособления лежит на работодателе уже с поправки, вступившей в силу в апреле 2016 года. Иначе говоря, ситуация «сотрудник не может пользоваться бизнес-приложением» давно в зоне обязанности. Насколько далеко идти в конкретном случае, зависит от обстоятельств: сверяйтесь с первичными источниками Канцелярии Кабинета министров и Министерства здравоохранения, труда и благосостояния Японии и решайте в диалоге с человеком, которого это касается.
Как программа чтения с экрана читает настольное приложение Windows?
Программы чтения с экрана вроде Экранного диктора (Narrator) и NVDA читают интерфейс приложения через платформу доступности UI Automation (UIA). Приложение публикует элементы экрана в дереве UIA; у каждого элемента есть свойства вроде Name (назначение) и ControlType (тип) и шаблоны элементов управления вроде Invoke (нажать) и Value (значение). Программа чтения объявляет это как «Подтвердить заказ, кнопка» и действует через шаблоны. Стандартные элементы WinForms и WPF уже умеют это, поэтому основная работа разработчика — не оставлять Name пустым, сделать интерфейс управляемым с клавиатуры и реализовать сведения на собственных элементах.
С чего начать в уже существующем приложении WinForms?
Самый короткий путь — прогнать FastPass в Accessibility Insights for Windows по нужному экрану и собрать элементы с пустым Name и сбои порядка табуляции. Исправления начинают с AccessibleName на кнопках только с иконкой, с привязки Label непосредственно перед полем в порядке табуляции и с TabIndex, совпадающего с визуальным порядком. Затем запустите Экранный диктор или NVDA, пройдите реальную рабочую операцию, не глядя на экран, и посмотрите, где вы застреваете. Не нужно исправлять все экраны сразу: начинайте с тех, которыми кто-то реально пользуется, а новые экраны сразу проводите по чек-листу.
Что делать для тем контрастности (высокой контрастности)?
База — не задавать цвета жёстко и опираться на системные цвета. В WinForms оставляйте ForeColor и BackColor по умолчанию или используйте SystemColors, определяйте состояние через SystemInformation.HighContrast и отслеживайте смену настроек событием UserPreferenceChanged. В WPF и WinUI, если ссылаетесь на ресурсы семейства SystemColors, смена темы подхватывается сама. Одновременно перестаньте передавать информацию одним цветом — например, показывать ошибку только красным — и добавляйте иконку или текст. Даже в обычной теме ориентир WCAG на коэффициент контрастности текста не ниже 4,5:1 делает интерфейс читаемее и в плохо освещённом цехе, и для возрастных пользователей.
Помогает ли доступность ещё и автоматическим UI-тестам?
Да. Инструменты автоматических UI-тестов вроде FlaUI опираются на ту же UI Automation, что и программы чтения с экрана. Name, ControlType и шаблоны элементов управления, которые вы готовите ради доступности, можно брать из тестового кода как есть, а AutomationId, заложенный для тестов, стабилизирует поиск элементов. Наоборот, интерфейс, который вы рисуете сами и который не попадает в дерево UIA, невидим и программе чтения, и тестам. Доступность и автоматические тесты — вложение в один и тот же фундамент: наведя порядок в одном, вы снижаете стоимость другого.

Об авторе

Страница с профилем автора статьи.

Го Комура

Представитель KomuraSoft LLC

Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.

Публичные ссылки

Вернуться в блог