Dẫn nhập khả năng tiếp cận ứng dụng Windows — Chuẩn bị cho UI Automation và yêu cầu điều chỉnh hợp lý
· Go Komura · Khả năng tiếp cận, UI Automation, Windows, WinForms, WPF, Điều chỉnh hợp lý, Trình đọc màn hình, Luật chống phân biệt đối xử người khuyết tật, Ứng dụng nghiệp vụ
“Một nhân sự giữa sự nghiệp bị khiếm thị không dùng được ứng dụng nhập đơn lõi bằng trình đọc màn hình. Họ dùng trình duyệt web và thư không khó, nhưng chỉ việc đọc của ứng dụng nghiệp vụ chúng tôi là không chạy đúng. Có làm được gì không?” — Các cuộc tư vấn kiểu này từ phòng IT khách hàng đang tăng.
Một bối cảnh là khung pháp lý. Sửa đổi 2021 của Đạo luật Xóa bỏ Phân biệt đối xử với Người khuyết tật có hiệu lực ngày 1 tháng 4 năm 2024, và “cung cấp điều chỉnh hợp lý” cho người khuyết tật trở thành nghĩa vụ với cả doanh nghiệp.1 Thêm nữa, quan hệ nhân viên–công ty như ở đoạn mở (lĩnh vực việc làm) thuộc Đạo luật Thúc đẩy Việc làm Người khuyết tật, vốn đã buộc người sử dụng lao động cung cấp điều chỉnh hợp lý từ tháng 4 năm 2016.2 Ý nghĩ “khả năng tiếp cận là chuyện website và không liên quan ứng dụng Windows nội bộ” không còn đứng, cả về luật lẫn thực tế.
Mặt khác, từ sàn phát triển, “chúng tôi không biết phải làm gì” là chỗ thành thật. Khả năng tiếp cận cho ứng dụng desktop Windows có ít thông tin hơn Web, và không có phép màu sau việc. Cũng không cần bi quan. Nếu bạn hiểu cơ chế trình đọc màn hình dùng để đọc một ứng dụng (UI Automation) và tiếp nhận nền tảng tên, bàn phím, và màu, khả năng dùng của ứng dụng nghiệp vụ tăng đáng kể. Và phần lớn đó là cải thiện nâng năng suất mọi người dùng, có hay không có khuyết tật.
Hướng tới các nhà phát triển ứng dụng nghiệp vụ Nhật Bản và nhân viên IT, bài viết này nối trong một lượt từ sắp xếp tối thiểu khung pháp lý và các chuẩn, qua cơ chế UI Automation, triển khai trong WinForms/WPF, thao tác bàn phím, màu và độ tương phản, cùng công cụ xác minh, tới cách đặt ưu tiên thực tế.
flowchart TB
accTitle: Luồng của bài viết này
accDescr: Cấu trúc bài viết này, nối lần lượt từ sắp xếp khung pháp lý và các chuẩn qua cơ chế UI Automation, triển khai trong WinForms và WPF, thao tác bàn phím, màu và độ tương phản, công cụ xác minh, và cách đặt ưu tiên
law["Sắp xếp khung pháp lý và các chuẩn"] --> uia["Cơ chế UI Automation"]
uia --> impl["Triển khai trong WinForms/WPF"]
impl --> kb["Thao tác bàn phím"]
kb --> color["Màu và độ tương phản"]
color --> verify["Công cụ xác minh"]
verify --> prio["Cách đặt ưu tiên"]
Hình 1: Bài viết này nối khung pháp lý qua cơ chế, triển khai, xác minh, và ưu tiên trong một dòng.
1. Kết luận trước
- Cung cấp điều chỉnh hợp lý đã là nghĩa vụ với cả doanh nghiệp từ ngày 1 tháng 4 năm 2024. Khi người khuyết tật bày tỏ ý định muốn một rào cản được gỡ, một phản hồi trong phạm vi không phải gánh nặng quá mức là bắt buộc. Lĩnh vực việc làm thuộc Đạo luật Thúc đẩy Việc làm Người khuyết tật, và điều đó đã là nghĩa vụ của người sử dụng lao động từ tháng 4 năm 2016.12
- Điều chỉnh hợp lý là quá trình “đáp một yêu cầu cá nhân qua đối thoại mang tính xây dựng”; làm ứng dụng dễ dùng hơn từ trước là “cải thiện môi trường” (nghĩa vụ nỗ lực). Hỗ trợ hoàn hảo từ trước không phải nghĩa vụ; điều quan trọng là không từ chối đối thoại một phía.1
- Tiêu chí kỹ thuật của khả năng tiếp cận tập trung ở WCAG (JIS X 8341-3:2016). JIS X 8341-3:2016 là chuẩn tương ứng có cùng nội dung với WCAG 2.0, và WCAG2ICT của W3C hướng dẫn áp dụng nó cho phần mềm không-Web. Một ứng dụng desktop có thể được kiểm theo cùng tư duy.34
- Trình đọc màn hình đọc ứng dụng qua UI Automation (UIA). Các thuộc tính mỗi phần tử trên cây UIA nắm — Name, ControlType, và tương tự — cùng các mẫu điều khiển như Invoke, Value, và SelectionItem là nguyên liệu cho công bố và thao tác.5
- Một nút Name trống được công bố chỉ là “nút”. Sửa ưu tiên cao nhất là đặt tên. WinForms dùng AccessibleName và gắn một Label với thứ tự tab; WPF dùng AutomationProperties.Name/LabeledBy.67
- Đạt mọi chức năng chỉ từ bàn phím là tiêu chí thành công WCAG (2.1.1) và, đồng thời, chính tốc độ nhập của người thao tác thành thạo. Đặt thứ tự tab, phím truy cập, và chỉ báo tiêu điểm nối thẳng tới hiệu quả cho mọi người dùng.8
- Lấy tỷ lệ tương phản chữ 4,5:1 trở lên làm hướng dẫn, và đừng truyền thông tin chỉ bằng màu. Trong chủ đề tương phản (tương phản cao), hãy tôn trọng màu hệ thống thay vì màu gắn cứng.89
- Kết hợp xác minh bằng FastPass trong Accessibility Insights for Windows và kiểm tay với trình đọc màn hình. Vì chúng ngồi trên cùng nền UIA, việc này cũng đền lẫn nhau với tài sản kiểm thử tự động UI như FlaUI.10
- Bạn không cần sửa mọi màn hình cùng lúc. Thứ tự thực tế là (1) từ các màn hình người dùng đó dùng, (2) phát triển mới tuân chuẩn, (3) lan ngang bằng cách sửa điều khiển dùng chung.
Trong một câu: hỗ trợ khả năng tiếp cận là “phơi đúng tên và thao tác trên cây UIA, và giữ nền tảng bàn phím cùng màu”.
2. Sắp xếp khung pháp lý và các chuẩn — Thứ “trở thành nghĩa vụ” đã đổi
2.1. Đạo luật Xóa bỏ Phân biệt đối xử với Người khuyết tật — Từ tháng 4 năm 2024, doanh nghiệp cũng bị buộc cung cấp điều chỉnh hợp lý
Đạo luật Xóa bỏ Phân biệt đối xử với Người khuyết tật là luật cấm “đối xử phân biệt bất công” với người khuyết tật bởi cơ quan hành chính và doanh nghiệp, và đòi “cung cấp điều chỉnh hợp lý”. Trong sửa đổi 2021 (Reiwa 3), cung cấp điều chỉnh hợp lý bởi doanh nghiệp, vốn là nghĩa vụ nỗ lực, trở thành nghĩa vụ, và đạo luật đã sửa có hiệu lực ngày 1 tháng 4 năm 2024 (Reiwa 6).1
Theo tờ rơi Văn phòng Nội các, cung cấp điều chỉnh hợp lý là đáp, trong phạm vi không phải gánh nặng quá mức, khi người khuyết tật bày tỏ ý định rằng cần một phản hồi nào đó để gỡ rào cản trong xã hội. Và vì nội dung khác theo đặc điểm khuyết tật, cảnh, và tình huống, một “đối thoại mang tính xây dựng” trong đó người khuyết tật và doanh nghiệp chồng đối thoại rồi cùng cân một phản hồi được nhấn mạnh. Từ chối đối thoại mang tính xây dựng một phía được nêu là có thể cấu thành vi phạm nghĩa vụ cung cấp điều chỉnh hợp lý.1
Hai phân biệt thực tế quan trọng ở đây.
- “Có hết mọi thứ sẵn từ trước” không phải thứ trở thành nghĩa vụ. Các biện pháp cải thiện từ trước nhằm tới số người khuyết tật không xác định — phía mềm như xem lại sổ tay và đào tạo, phía cứng như làm cơ sở không rào cản — được gọi là “cải thiện môi trường”, và đây là nghĩa vụ nỗ lực.1 Đưa ứng dụng nghiệp vụ vào trạng thái dùng được với trình đọc màn hình từ trước có thể nghĩ như một nỗ lực cải thiện môi trường. Cải thiện môi trường đã đi càng xa, gánh nặng cung cấp điều chỉnh hợp lý cá nhân càng nhẹ.
- Lĩnh vực việc làm không thuộc Đạo luật Xóa bỏ Phân biệt đối xử với Người khuyết tật mà thuộc Đạo luật Thúc đẩy Việc làm Người khuyết tật. Cùng tờ rơi cũng nêu việc làm và công việc tuân các điều khoản của Đạo luật Thúc đẩy Việc làm Người khuyết tật.1 Và dưới đạo luật đó, theo sửa đổi có hiệu lực tháng 4 năm 2016 (Heisei 28), cấm phân biệt khuyết tật trong việc làm và cung cấp điều chỉnh hợp lý trong phạm vi không phải gánh nặng quá mức đã được buộc với người sử dụng lao động.2 Cuộc tư vấn mở “một nhân viên không dùng được ứng dụng nghiệp vụ” thực tế đã nằm trong phạm vi nghĩa vụ từ lâu trước 2024.
flowchart TB
accTitle: Vị trí điều chỉnh hợp lý và cải thiện môi trường
accDescr: Quan hệ giữa doanh nghiệp nói chung và người khuyết tật thuộc Đạo luật Xóa bỏ Phân biệt đối xử với Người khuyết tật, và cung cấp điều chỉnh hợp lý bằng cách đáp yêu cầu cá nhân qua đối thoại mang tính xây dựng đã là nghĩa vụ từ tháng 4 năm 2024; lĩnh vực việc làm đã là nghĩa vụ của người sử dụng lao động từ tháng 4 năm 2016 dưới Đạo luật Thúc đẩy Việc làm Người khuyết tật; làm ứng dụng dễ dùng hơn từ trước là cải thiện môi trường, nghĩa vụ nỗ lực
scene{"Cảnh nào?"}
scene -->|Doanh nghiệp + khuyết tật| kaisho["Đạo luật phân biệt"]
scene -->|Việc làm / công việc| koyou["Đạo luật việc làm"]
kaisho --> moushide["Yêu cầu qua đối thoại"]
moushide --> hairyo["Cung cấp điều chỉnh"]
hairyo -.-> hairyoN["Nghĩa vụ từ 2024"]
koyou --> koyougimu["Cung cấp điều chỉnh"]
koyougimu -.-> koyouN["Nghĩa vụ từ 2016"]
kaisho -.-> kankyo["Ứng dụng dễ hơn từ trước"]
kankyo -.-> kankyoN["Cải thiện môi trường"]
kankyoN -.-> kankyoN2["nghĩa vụ nỗ lực"]
kankyo -.-> moushide
Hình 2: Đạo luật điều chỉnh tách theo cảnh; điều chỉnh hợp lý là nghĩa vụ, và sửa từ trước là cải thiện môi trường, nghĩa vụ nỗ lực.
Cách một vụ cá nhân được luật xử lý phụ thuộc tình huống. Bài viết này không bước vào giải thích pháp lý; nó đi từ góc nhìn một kỹ sư có thể làm gì khi được yêu cầu phản hồi. Với nguồn gốc, hãy tham chiếu tài liệu Văn phòng Nội các và Bộ Y tế, Lao động và Phúc lợi.12
2.2. JIS X 8341-3 và WCAG — “Tiêu chí Web” cũng kéo sang phần mềm
Ở phía tiêu chí kỹ thuật, chúng tập trung ở JIS X 8341-3:2016. Chuẩn này là chuẩn tương ứng của ISO/IEC 40500:2012, và thân chuẩn có cùng nội dung với WCAG 2.0 của W3C.3 Nếu muốn biết cụ thể “hỗ trợ khả năng tiếp cận” gồm gì, đọc các tiêu chí thành công WCAG (nay được mở rộng trong WCAG 2.1/2.2) là đường ngắn nhất, và bản dịch tiếng Nhật của WAIC cũng được xuất bản.8
Câu hỏi “WCAG có phải tiêu chí cho nội dung Web?” là chính đáng, nhưng W3C đã sắp xếp, trong một Group Note gọi là WCAG2ICT (Guidance on Applying WCAG 2 to Non-Web Information and Communications Technologies), cách áp dụng các tiêu chí thành công WCAG 2.0/2.1/2.2 cho tài liệu và phần mềm không-Web.4 Nói cách khác, tư duy như “văn bản thay thế”, “độ tương phản”, “thao tác bàn phím”, và “màu không phải phương tiện duy nhất” có thể áp dụng cho ứng dụng desktop Windows trong cùng khung với Web. Từ Chương 3 trở đi bài viết này thả tư duy đó xuống triển khai WinForms/WPF cụ thể.
flowchart TB
accTitle: Quan hệ giữa JIS X 8341-3 và WCAG
accDescr: JIS X 8341-3:2016 là chuẩn tương ứng có cùng nội dung với WCAG 2.0, và WCAG2ICT cho thấy cách áp dụng tiêu chí thành công WCAG cho phần mềm không-Web, nên một ứng dụng desktop Windows có thể được kiểm trong cùng khung
wcag["WCAG 2.0(W3C)"] ---|Một chuẩn tương ứng có cùng nội dung| jis["JIS X 8341-3:2016"]
wcag --> ict["WCAG2ICT"]
ict --> soft["Áp dụng cho phần mềm không-Web"]
soft --> app["Một ứng dụng desktop Windows"]
Hình 3: JIS X 8341-3:2016 là chuẩn tương ứng của WCAG 2.0, và WCAG2ICT kéo cùng tiêu chí sang ứng dụng desktop.
3. Công nghệ hỗ trợ đọc ứng dụng thế nào — Bộ ba UI Automation
3.1. Cây UIA, thuộc tính, và mẫu điều khiển
Windows có sẵn một nền tảng khả năng tiếp cận gọi là UI Automation (UIA). UIA là cơ chế cho công nghệ hỗ trợ như trình đọc màn hình lấy thông tin UI và thao tác UI bằng phương tiện khác đầu vào chuẩn, và nó trung gian giữa phía ứng dụng (nhà cung cấp) và phía công nghệ hỗ trợ (máy khách).5
Thế giới UIA có thể hiểu như bộ ba sau.5
| Phần tử | Vai trò | Ví dụ đại diện |
|---|---|---|
| Cây UIA | Một cây bắt đầu từ desktop làm gốc rồi tiếp cửa sổ → điều khiển. Công nghệ hỗ trợ đi cây này để nắm UI | Cửa sổ, ngăn, nút, hộp sửa |
| Thuộc tính | Các giá trị biểu diễn bản chất mỗi phần tử | Name (mục đích), ControlType (loại), AutomationId (định danh), IsEnabled, IsKeyboardFocusable |
| Mẫu điều khiển | Từ vựng “thao tác bạn làm được” theo loại | Invoke (nhấn), Value (đọc/ghi giá trị), SelectionItem (chọn), Toggle (bật/tắt), ExpandCollapse (mở/thu) |
Khi trình đọc màn hình tiêu điểm một nút, lời công bố “nút Xác nhận đơn” đại khái là tổ hợp Name + loại điều khiển. Khi người dùng làm thao tác “thực hiện”, công nghệ hỗ trợ nhấn nút đó qua mẫu Invoke. Nói cách khác, nếu Name và các mẫu được phơi đúng thì đọc và thao tác được; nếu không được phơi, cũng như không tồn tại dù nhìn thấy trên màn hình.
flowchart TB
accTitle: Bộ ba UI Automation
accDescr: Ứng dụng, với tư cách nhà cung cấp, phơi thuộc tính và mẫu điều khiển của mỗi phần tử trên cây UIA; trình đọc màn hình, với tư cách máy khách, công bố Name và ControlType rồi thao tác qua các mẫu như Invoke
app["Ứng dụng(nhà cung cấp)"] --> tree["Cây UIA"]
tree --> prop["Thuộc tính(Name, ControlType, và tương tự)"]
tree --> pat["Mẫu(Invoke, Value, và tương tự)"]
sr["Trình đọc màn hình(máy khách)"] -->|Công bố| prop
sr -->|Thao tác| pat
Hình 4: Trình đọc màn hình dùng thuộc tính và mẫu ứng dụng đã phơi trên cây UIA cho công bố và thao tác.
3.2. Trình đọc màn hình là máy khách UIA
Các trình đọc màn hình chính dùng trên Windows gồm Narrator, có sẵn trong Windows; NVDA,11 miễn phí và nguồn mở; và PC-Talker, sản phẩm thương mại dùng rộng ở Nhật. Phong cách công bố khác nhau giữa chúng, nhưng đường chính để đọc UI ứng dụng desktop là UIA trong mọi trường hợp. Đó là vì sao phản hồi phía ứng dụng không phải “hỗ trợ một trình đọc màn hình cụ thể” mà tập trung vào phơi đúng thông tin cho UIA.
flowchart TB
accTitle: Đường chung của các trình đọc màn hình chính
accDescr: Nếu ứng dụng phơi đúng thông tin cho UIA, Narrator, NVDA, và PC-Talker đều đọc được UI theo cùng đường, nên phản hồi phía ứng dụng không nhằm một trình đọc màn hình cụ thể mà tập trung vào phơi cho UIA
app["Ứng dụng"] -->|Phơi thông tin| uia["UI Automation(UIA)"]
uia --> nar["Narrator"]
uia --> nvda["NVDA"]
uia --> pct["PC-Talker"]
app -.-> goal["Phản hồi tập trung vào phơi cho UIA"]
Hình 5: Các trình đọc màn hình chính đều lấy UIA làm đường, nên phản hồi của ứng dụng tập trung vào phơi cho UIA.
3.3. Một “nút Name trống” được công bố thành gì?
Một ví dụ cụ thể. Giả sử thanh công cụ có nút Lưu chỉ hiện biểu tượng đĩa mềm. Với người nhìn thấy, biểu tượng truyền nghĩa, nhưng nếu Name để trống, trình đọc màn hình công bố nút này chỉ là “nút”. Nếu “Mở” và “In” bên cạnh cũng vậy, người dùng chỉ nghe “nút, nút, nút” và không có cách biết cái nào là cái nào. Hướng dẫn sửa khả năng tiếp cận của Microsoft cũng liệt kê nút không Name, và ảnh được công bố chỉ là “Image”, như các vấn đề đại diện làm dừng việc của người dùng.7
May là cả điều khiển chuẩn WinForms lẫn WPF đều có hỗ trợ UIA từ đầu, và trong nhiều trường hợp Name được quyết tự động từ chữ hoặc nhãn. Thứ vỡ thường là một trong (1) chỉ-biểu tượng, không có nguyên liệu cho tên, (2) không gắn với nhãn, hoặc (3) vẽ tùy chỉnh không đặt thông tin lên cây UIA. Hai chương tiếp nhìn cách sửa theo từng khung.
flowchart TB
accTitle: Ba cách điển hình khiến công bố vỡ
accDescr: Công bố vỡ khi không có nguyên liệu cho tên vì chỉ-biểu tượng, khi không gắn với nhãn, hoặc khi vẽ tùy chỉnh không đặt thông tin lên cây UIA, và kết cục được công bố chỉ là nút
c1["Chỉ-biểu tượng, không nguyên liệu"] --> broken["Name trở nên trống"]
c2["Không gắn với nhãn"] --> broken
c3["Vẽ tùy chỉnh không đưa thông tin"] --> broken
broken --> result["Công bố chỉ là nút"]
Hình 6: Công bố vỡ thường quy về một trong ba mẫu: thiếu nguyên liệu tên, thiếu gắn kết, hoặc vẽ tùy chỉnh.
4. Triển khai trong WinForms — AccessibleName và thứ tự tab
4.1. Điều khiển mà Text trở thành Name tự động, và điều khiển mà Text không
Trong WinForms, điều khiển hiện chữ, như Button hoặc CheckBox, dùng giá trị thuộc tính Text làm Name UIA. Mặt khác, ComboBox, ListBox, ListView, PictureBox, ProgressBar, TabControl, TextBox, TreeView và tương tự không biến Text thành Name. Những cái này cần tên bằng phương tiện khác.6
Cách dễ bảo trì nhất là đặt một Label mô tả ở thứ tự tab ngay trước điều khiển đích. Nếu bạn đặt TabIndex của điều khiển đích tới ngay sau TabIndex của Label, chữ của Label đó được dùng tự động làm Name UIA. Nhãn nhìn thấy trên màn hình và lời công bố khớp, và bạn không phải quản lý lời hai lần.612
Nếu không đặt được Label, hãy đặt AccessibleName tường minh. Bạn cũng có thể đặt AccessibleDescription nếu cần giải thích bổ sung, và AccessibleRole nếu vai trò khác với vẻ ngoài.13
flowchart TB
accTitle: Tên điều khiển WinForms được quyết thế nào
accDescr: Với Button và tương tự, Text trở thành Name UIA nguyên si; với điều khiển như TextBox mà Text không được tái dùng, chữ của một Label đặt ở thứ tự tab ngay trước được dùng; nếu không đặt được Label, hãy đặt AccessibleName tường minh
ctrl["Điều khiển"] --> qtext{"Một loại mà Text trở thành Name?"}
qtext -->|Có| usetext["Text trở thành Name nguyên si"]
qtext -->|Không| qlabel{"Một Label ở thứ tự tab ngay trước?"}
qlabel -->|Có| uselabel["Chữ của Label được dùng làm Name"]
qlabel -->|Không| explicit["Đặt AccessibleName tường minh"]
Hình 7: Với Name WinForms, hãy chọn cách quyết theo thứ tự Text, một Label ở thứ tự tab ngay trước, AccessibleName.
// An icon-only toolbar button: state the name for announcement explicitly
saveToolStripButton.AccessibleName = "Save";
// An image-only button: name + a supplementary explanation
btnSearchCustomer.AccessibleName = "Search customer";
btnSearchCustomer.AccessibleDescription = "Search the customer master by customer code or name";
// Set it directly on an input field where you cannot place a Label in the immediately preceding tab order
txtOrderNo.AccessibleName = "Order number";
// A PictureBox reused as a chart display: match the role to the reality as well
pictureBoxChart.AccessibleRole = AccessibleRole.Chart;
pictureBoxChart.AccessibleName = "Monthly order-count chart";
Một lưu ý: nếu bạn đặt AccessibleName một lần trong ngăn Properties của Visual Studio rồi xóa, một thiết lập chuỗi-rỗng có thể còn trong tệp designer và cản giải tên mặc định. Hãy xóa dòng tương ứng khỏi tệp designer.6
flowchart TB
accTitle: Vấn đề AccessibleName chuỗi-rỗng còn lại
accDescr: Nếu bạn đặt AccessibleName một lần trong ngăn Properties rồi xóa, một thiết lập chuỗi-rỗng còn trong tệp designer và cản giải tên mặc định, nên bạn sửa bằng cách xóa dòng tương ứng khỏi tệp designer
set["Đặt AccessibleName"] --> erase["Xóa trong ngăn Properties"]
erase --> remain["Thiết lập chuỗi-rỗng còn lại"]
remain --> block["Nó cản giải tên mặc định"]
block -.-> fix["Xóa dòng tương ứng khỏi tệp designer"]
Hình 8: Xóa trong ngăn Properties vẫn để lại chuỗi rỗng, nên bạn sửa bằng cách xóa dòng tương ứng khỏi tệp designer.
4.2. Các cải thiện thường gặp trên màn hình nhập đơn
Những chỗ chúng tôi thực sự hay sửa trong ứng dụng nghiệp vụ được tóm thành danh sách kiểm.
| Trạng thái thường gặp | Vấn đề | Cách sửa |
|---|---|---|
| ToolStripButton chỉ-biểu tượng | Công bố chỉ là “nút” | Đặt AccessibleName |
| Có Label gần TextBox nhưng thứ tự tab rời rạc | Tên trường nhập trống, hoặc thành tên không liên quan | Đặt trường nhập ngay sau TabIndex của Label |
| PictureBox dùng như nút qua Click | Vai trò không được truyền như nút, và không nhấn được từ bàn phím | Thay bằng Button, hoặc đặt AccessibleRole/AccessibleName cộng hỗ trợ bàn phím |
| Tiêu đề cột DataGridView trống hoặc chỉ ký hiệu | Nghĩa cột không rõ khi một ô được công bố | Đặt tên cột có nghĩa trên HeaderText |
| Chỉ Panel được dùng để nhóm nội dung, và tiêu đề là ảnh | Bạn không biết đó là nhóm nhập nào | Dùng GroupBox, hoặc làm tiêu đề thành Label |
Mỗi cái là sửa vài dòng, nhưng với người dùng trình đọc màn hình đó là ngã ba giữa “màn hình không dùng được” và “màn hình dùng được”.
5. Triển khai trong WPF — AutomationProperties và AutomationPeer
5.1. AutomationProperties.Name / LabeledBy / HelpText
Trong WPF, điều khiển mà Content là chuỗi, như Button, dùng nội dung đó làm Name UIA. Nút chỉ-biểu tượng (Image hoặc Path) không có nguyên liệu cho Name, nên bạn nêu bằng AutomationProperties.Name, hoặc nếu có chữ hiện gần đó bạn gắn bằng AutomationProperties.LabeledBy.7
TextBox có một lưu ý quan trọng. Text của TextBlock được tái dùng làm Name, nhưng Text của TextBox được phơi ở phía thuộc tính Value UIA và không trở thành Name. Với trường nhập, gắn TextBlock nhãn-hiển thị bằng LabeledBy là ứng viên đầu. Công bố và hiện trên màn hình khớp, và bạn cũng tránh quản lý lời hai lần.14
<!-- An input field: associate the display label with LabeledBy -->
<TextBlock x:Name="OrderNoLabel" Text="Order number" />
<TextBox
AutomationProperties.LabeledBy="{Binding ElementName=OrderNoLabel}"
AutomationProperties.AutomationId="OrderNoTextBox" />
<!-- An icon-only button: state the name, and a supplement if needed -->
<Button
AutomationProperties.Name="Confirm order"
AutomationProperties.HelpText="Confirm the order being entered and allocate inventory">
<Path Data="{StaticResource CheckIconGeometry}" Width="16" Height="16" />
</Button>
flowchart TB
accTitle: Tên điều khiển WPF được quyết thế nào
accDescr: Điều khiển mà Content là chuỗi dùng nội dung đó làm Name; nếu không, gắn nhãn hiện gần đó bằng LabeledBy là ứng viên đầu; nếu cái đó cũng vắng, hãy nêu AutomationProperties.Name; Text của TextBox được phơi ở phía Value, không phải Name
ctrl["Điều khiển"] --> qc{"Content có phải chuỗi?"}
qc -->|Có| auto["Nội dung trở thành Name"]
qc -->|Không| ql{"Nhãn hiện gần đó?"}
ql -->|Có| lb["Gắn bằng LabeledBy"]
ql -->|Không| nm["Đặt Name tường minh"]
tbx["Text của TextBox"] -.-> val["Được phơi như Value, không phải Name"]
Hình 9: Với Name WPF, hãy quyết theo thứ tự chuỗi Content, LabeledBy, đặt tường minh; Text của TextBox không trở thành Name.
Thông tin bổ sung không vừa trong Name có thể được phơi bằng AutomationProperties.HelpText.7 Ngoài ra, AutomationId là định danh dùng để nhận diện phần tử trong kiểm thử tự động UI, nên quyết một quy ước đặt tên lúc thiết kế màn hình sẽ đền sau (được trình bày sâu trong “Kiểm thử tự động UI cho ứng dụng desktop Windows”).
5.2. Điều khiển tùy chỉnh cần một AutomationPeer
Một điều khiển tùy chỉnh bạn tự vẽ không thể, nguyên si, phơi thông tin có nghĩa trên cây UIA. Trong WPF bạn ghi đè OnCreateAutomationPeer trên lớp dẫn xuất UIElement và trả một lớp dẫn xuất AutomationPeer để phơi tên, loại, và mẫu. Nếu bạn đang kế thừa điều khiển sẵn có, kế thừa Peer tương ứng (ButtonBaseAutomationPeer cho ButtonBase) cho phép bạn tiếp nhận hành vi đã triển khai.15
flowchart TB
accTitle: Thông tin được phơi qua AutomationPeer thế nào
accDescr: Điều khiển tùy chỉnh phơi tên, loại, và mẫu bằng cách ghi đè OnCreateAutomationPeer rồi trả một lớp dẫn xuất AutomationPeer; nếu bạn đang kế thừa điều khiển sẵn có, hãy kế thừa Peer tương ứng và tiếp nhận hành vi đã triển khai
custom["Điều khiển tùy chỉnh"] --> ov["OnCreateAutomationPeer"]
ov --> peer["Trả một lớp dẫn xuất Peer"]
peer --> pub["Phơi tên, loại, và mẫu"]
inherit["Kế thừa điều khiển sẵn có"] -.-> basepeer["Kế thừa Peer tương ứng"]
basepeer -.-> reuse["Tiếp nhận hành vi đã triển khai"]
Hình 10: Điều khiển tùy chỉnh trả một Peer từ OnCreateAutomationPeer và phơi thông tin cho UIA.
// An example of a control that custom-draws line status as a coloured 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 a UIA property-changed event the moment the value changes. Without this,
// a screen reader keeps the old name and cannot notice 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-equivalent if it is a status display with no operation
protected override string GetNameCore()
=> StatusLamp.NameFor(((StatusLamp)Owner).IsOnline);
}
Trả một tên chưa đủ; nói với nó bằng sự kiện ngay lúc đổi cũng là việc của Peer. Công nghệ hỗ trợ không có thời điểm riêng để lấy lại giá trị, nên một triển khai không phát sự kiện thay đổi ở trạng thái “đúng chỉ khi được hỏi lại”, và người dùng trình đọc màn hình không được nói về thay đổi trạng thái.
sequenceDiagram
accTitle: Luồng nói với trình đọc màn hình về thay đổi trạng thái
accDescr: Ngay lúc giá trị điều khiển đổi, AutomationPeer phát sự kiện thay đổi thuộc tính Name; công nghệ hỗ trợ không tự lấy lại, nên không có sự kiện thì nó ở lại tên cũ và không nhận ra thay đổi
participant c as Điều khiển
participant p as AutomationPeer
participant s as Trình đọc màn hình
c->>p: Giá trị IsOnline đổi
p->>s: Phát sự kiện thay đổi thuộc tính Name
s->>s: Công bố trạng thái mới
Note over s: Không có sự kiện thì ở lại tên cũ
Hình 11: Thay đổi giá trị tới trình đọc màn hình chỉ khi AutomationPeer nói với nó bằng sự kiện thay đổi.
Nếu điều khiển tùy chỉnh có thao tác (nhấn được, đổi giá trị được, chọn được), bạn ghi đè GetPattern và cung cấp giao diện mẫu như IInvokeProvider hoặc IRangeValueProvider.15 Điểm là nếu bạn cũng xây Peer ở phía thư viện-điều-khiển-chung, mọi màn hình dùng nó được hỗ trợ tự động. Đó là nền của “lan ngang” Chương 9.
6. Bạn có đạt mọi chức năng chỉ từ bàn phím không?
Tiêu chí thành công WCAG 2.1.1 (Keyboard) đòi mọi chức năng của nội dung thao tác được qua giao diện bàn phím.8 Người dùng trình đọc màn hình về nguyên tắc không dùng chuột, nên chức năng bạn không đạt từ bàn phím cũng như chức năng không tồn tại. Các góc kiểm như sau.
| Góc nhìn | Việc xác nhận | Phương tiện chính trong WinForms / WPF |
|---|---|---|
| Thứ tự tab | Thứ tự di chuyển phím Tab có khớp thứ tự nhìn (trên-trái → dưới-phải) không? | Dọn TabIndex, đặt TabStop |
| Phím truy cập | Bạn có tới thẳng một mục chính bằng Alt+một chữ không? | Trong WinForms, & trong Text; trong WPF, _ trong tiêu đề |
| Phím tắt | Có phím độc lập cho thao tác thường (lưu, tìm, xác nhận) không? | Gán Ctrl+S và tương tự, hiện trên menu |
| Chỉ báo tiêu điểm | Bạn có theo bằng mắt tiêu điểm đang ở đâu không? | Đừng bỏ hình chữ nhật tiêu điểm; tự vẽ khi bạn vẽ tùy chỉnh |
| Chức năng chỉ-chuột | Có chức năng chỉ dùng được bằng nhấp đúp, nhấp phải, kéo, hoặc hover không? | Cũng cung cấp cùng chức năng từ menu hoặc phím |
| Hộp thoại | Enter = nút mặc định và Esc = hủy có chạy không? | AcceptButton/CancelButton, IsDefault/IsCancel |
Bài hướng dẫn khả năng tiếp cận WinForms cũng liệt kê, như nền tảng, đặt nhãn ở thứ tự tab ngay trước trường nhập, và đặt phím truy cập trên các điều khiển và menu người dùng muốn tới.12
Điều chúng tôi muốn nhấn là đây không phải “chi phí thêm cho hỗ trợ khuyết tật”. Trong công việc thường nhật như nhập đơn, việc hoàn tất nhập mà không rời tay khỏi vị trí home chính là thứ quyết định thông lượng của người thao tác nguyên si. Thứ tự tab lộn xộn hoặc thao tác đòi chuột là khuyết điểm mỗi ngày cắt một ít năng suất mọi người dùng. Hỗ trợ khả năng tiếp cận và hiệu quả bàn phím chỉ là hai tên của cùng một việc (với ưu tiên theo môi trường dùng, cũng xem “Thiết kế UX ứng dụng Windows”).
flowchart TB
accTitle: Hiệu ứng kép của việc dọn bàn phím
accDescr: Dọn thứ tự tab, phím truy cập, và chỉ báo tiêu điểm tạo hai hiệu ứng cùng lúc — người dùng công nghệ hỗ trợ đạt được chức năng, và tốc độ nhập của mọi người thao tác — và chức năng chỉ dùng được bằng chuột cũng như chức năng không tồn tại
seibi["Dọn bàn phím"] --> a11y["Người dùng công nghệ hỗ trợ"]
seibi --> speed["Tốc độ mọi người thao tác"]
mouse["Chức năng chỉ-chuột"] -.-> none["Cũng như không tồn tại"]
Hình 12: Dọn thao tác bàn phím thực hiện hỗ trợ công nghệ hỗ trợ và hiệu quả cho mọi người dùng cùng lúc; chức năng chỉ-chuột cũng như không tồn tại.
7. Màu và độ tương phản — 4,5:1 và “Màu không phải phương tiện duy nhất”
7.1. Hướng dẫn tỷ lệ tương phản là 4,5:1
Tiêu chí thành công WCAG 1.4.3 (Contrast (Minimum)) đòi tỷ lệ tương phản ít nhất 4,5:1 cho chữ và ảnh chữ, và ít nhất 3:1 cho chữ lớn.8 Một thiết kế hiện đại đặt chữ xám nhạt trên nền trắng không hiếm khi trượt tiêu chí này. Người dùng ứng dụng nghiệp vụ gồm người thị lực và thị giác màu đã đổi theo tuổi, và người dùng trong môi trường tối như nhà máy. Hãy thành thói quen đo bằng bộ kiểm tương phản lúc rà soát thiết kế.
7.2. Đừng truyền thông tin chỉ bằng màu
Tiêu chí thành công 1.4.1 (Use of Color) là màu không được là phương tiện nhìn duy nhất để truyền thông tin.8 Các ví dụ điển hình trong ứng dụng nghiệp vụ như sau.
- Hiện hàng lỗi chỉ bằng chữ đỏ → cũng cung cấp biểu tượng lỗi và cột thông báo
- Hiện trường bắt buộc chỉ bằng màu nhãn → thêm “*” hoặc lời “Bắt buộc”
- Hiện trạng thái chỉ bằng màu đèn → làm thành màu + hình, hoặc lời (“Đang chạy”, “Đã dừng”)
Với sự đa dạng của thị giác màu, đây cũng không phải “phản hồi đặc biệt” mà là nền tảng thiết kế hiển thị.
flowchart TB
accTitle: Thay thông tin truyền chỉ bằng màu
accDescr: Hiển thị hiện lỗi chỉ bằng chữ đỏ được thay bằng biểu tượng lỗi cộng cột thông báo; hiển thị hiện trường bắt buộc chỉ bằng màu nhãn được thay bằng thêm lời Bắt buộc; hiển thị hiện trạng thái chỉ bằng màu đèn được thay bằng kết hợp hình hoặc lời
err["Lỗi chỉ chữ đỏ"] --> erra["Cũng cung cấp biểu tượng và lời"]
req["Bắt buộc chỉ từ màu nhãn"] --> reqa["Thêm lời Bắt buộc"]
lamp["Trạng thái chỉ từ màu đèn"] --> lampa["Kết hợp màu với hình hoặc lời"]
Hình 13: Các ví dụ điển hình truyền chỉ bằng màu được thay bằng kết hợp biểu tượng, lời, cùng hình hoặc chữ.
7.3. Theo một chủ đề tương phản (tương phản cao)
Windows có chủ đề tương phản (trước đây tương phản cao) chuyển sang bảng màu tách mạnh tiền cảnh và nền; người dùng có thể chọn và sửa các chủ đề dựng sẵn được thiết kế sao cho tỷ lệ tương phản nói chung 7:1 trở lên.9 Nguyên tắc phía ứng dụng đơn giản: đừng gắn cứng màu; hãy tôn trọng màu hệ thống.
- WinForms: nếu bạn để ForeColor/BackColor ở mặc định, thiết lập màu của người dùng được dùng. Chỗ bạn đã áp màu riêng, hãy phán bằng SystemInformation.HighContrast, chuyển sang bảng dựa trên SystemColors, và theo thay đổi thiết lập bằng sự kiện UserPreferenceChanged.12
- WPF/WinUI: nếu bạn tham chiếu tài nguyên lớp SystemColors, bạn theo chuyển chủ đề. Chỗ bạn đã tô bằng cọ riêng trở thành nguyên nhân vỡ.9
flowchart TB
accTitle: Theo một chủ đề tương phản
accDescr: Chỗ màu bị gắn cứng vỡ khi chuyển sang chủ đề tương phản, nên hãy chuyển sang bảng dựa trên SystemColors và theo bằng sự kiện đổi thiết lập; nếu bạn tham chiếu màu hệ thống bạn theo màu người dùng tự động
theme["Chuyển sang chủ đề tương phản"] --> qh{"Màu được chỉ thế nào?"}
qh -->|Gắn cứng| broken["Bảng màu vỡ"]
qh -->|Tham chiếu màu hệ thống| ok["Tự động theo màu người dùng"]
broken -.-> fix["Chuyển sang SystemColors"]
fix -.-> ev["Theo bằng sự kiện đổi thiết lập"]
Hình 14: Chỉ chỗ màu bị gắn cứng mới vỡ dưới chủ đề tương phản; tham chiếu màu hệ thống theo tự động.
Ngoài ra, người dùng thị lực thấp thường dùng độ phóng OS cao (co giãn DPI), nên hỗ trợ DPI cao cũng là một phần hỗ trợ khả năng tiếp cận. Ứng dụng bố cục vỡ ở 125%–200% không dùng được ngay lúc đó. Xem “Hỗ trợ DPI cao trong WinForms” và “Hỗ trợ DPI cao WPF” cho chi tiết.
8. Xác minh trong thực tế — Accessibility Insights và kiểm tay trình đọc màn hình
8.1. Accessibility Insights for Windows
Microsoft cung cấp Accessibility Insights for Windows như công cụ xác minh khả năng tiếp cận cho ứng dụng Windows, với ba cách dùng chính.10
- Live Inspect: chỉ cần đưa chuột lên một phần tử hoặc tiêu điểm bằng bàn phím, và bạn xác nhận được thuộc tính UIA của nó (Name, ControlType, mẫu, và tương tự). Phương tiện ngắn nhất để thấy “Name của nút này là gì”.
- FastPass: kiểm nhẹ phát hiện các vấn đề khả năng tiếp cận tác động cao trong dưới năm phút. Các vấn đề phán được bằng máy, như thiếu Name, có thể được lập danh sách theo từng màn hình mới.
- Troubleshooting: hỗ trợ chẩn đoán và sửa một vấn đề cụ thể. Từ vấn đề đã phát hiện bạn đi thẳng tới các hướng dẫn sửa theo khung mà bài này cũng trích.
Inspect.exe và AccEvent, nằm trong Windows SDK, cũng xác nhận được cây UIA và thuộc tính, nhưng chúng được định vị như công cụ kế thừa, và chuyển sang Accessibility Insights nay được khuyến nghị.10
flowchart TB
accTitle: Ba cách dùng Accessibility Insights
accDescr: Accessibility Insights for Windows cung cấp xác nhận thuộc tính UIA bằng Live Inspect, kiểm nhẹ các vấn đề tác động cao bằng FastPass, và hỗ trợ chẩn đoán rồi sửa một vấn đề bằng Troubleshooting; chuyển từ các công cụ kế thừa như Inspect.exe được khuyến nghị
ai["Accessibility Insights"] --> live["Live Inspect"]
ai --> fast["FastPass"]
ai --> ts["Troubleshooting"]
live --> livef["Xác nhận thuộc tính UIA"]
fast --> fastf["Phát hiện vấn đề tác động cao"]
ts --> tsf["Hỗ trợ chẩn đoán và sửa"]
legacy["Inspect.exe và tương tự"] -.->|Chuyển được khuyến nghị| ai
Hình 15: Accessibility Insights có ba cách dùng xác nhận, phát hiện, và chẩn đoán, và là đích chuyển từ các công cụ kế thừa.
8.2. Kiểm tay với trình đọc màn hình
Thứ kiểm tự động của một công cụ phát hiện được chỉ là các vấn đề phán được bằng máy. Cuối cùng, luôn đi một thao tác nghiệp vụ thật với trình đọc màn hình. Narrator có sẵn trong Windows khởi động ngay bằng Ctrl+phím Windows+Enter, và NVDA giới thiệu được miễn phí.11 Mẹo của lần kiểm là thử, không nhìn màn hình (hoặc tắt màn hình), chỉ dựa vào lời công bố, liệu bạn hoàn tất được một việc thật như “nhập một đơn rồi xác nhận”. Các vấn đề như tên có mặt nhưng thứ tự công bố không mạch, hoặc tiêu điểm thoát ra ngoài hộp thoại, chỉ tìm thấy khi làm tay.
flowchart TB
accTitle: Kết hợp xác minh công cụ và kiểm tay
accDescr: Thứ kiểm tự động như FastPass phát hiện được chỉ là các vấn đề phán được bằng máy; phần còn lại tìm thấy khi làm tay bằng cách đi một thao tác nghiệp vụ thật với trình đọc màn hình rồi tìm vấn đề thứ tự-công-bố và tiêu điểm
tool["Kiểm tự động của công cụ"] --> kikai["Các vấn đề phán được bằng máy"]
tool -.-> nokori["Các vấn đề nó không phát hiện còn lại"]
nokori --> sr["Kiểm tay với trình đọc màn hình"]
sr --> task["Đi một thao tác nghiệp vụ"]
task --> mieru["Vấn đề thứ tự-công-bố và tiêu điểm"]
Hình 16: Lập danh sách vấn đề máy được bằng kiểm tự động, và tìm phần còn lại bằng kiểm tay với trình đọc màn hình.
8.3. Xây vào luồng phát triển, và phần đền lẫn với kiểm thử tự động UI
Để xác minh không thành phụ thuộc người, chúng tôi khuyến nghị xây danh sách kiểm sau vào các mục rà soát cho màn hình mới.
| # | Mục kiểm | Phương tiện |
|---|---|---|
| 1 | FastPass không lỗi | Accessibility Insights |
| 2 | Mọi trường nhập và nút có Name | Live Inspect |
| 3 | Bạn đạt mọi chức năng chỉ bằng phím Tab | Thủ công |
| 4 | Enter/Esc và các phím tắt chính chạy | Thủ công |
| 5 | Tỷ lệ tương phản chữ 4,5:1 trở lên | Bộ kiểm tương phản |
| 6 | Không vỡ dưới chủ đề tương phản | Chuyển chủ đề rồi kiểm bằng mắt |
| 7 | Không vỡ ở co giãn 200% | Đổi thiết lập hiển thị rồi kiểm bằng mắt |
| 8 | Bạn hoàn tất một việc đại diện bằng trình đọc màn hình | Narrator/NVDA |
Và thêm một điều. Kiểm thử tự động UI với FlaUI và tương tự được xây trên cùng UIA mà trình đọc màn hình dùng. Name và các mẫu bạn đặt cho khả năng tiếp cận trở thành bộ phận mã kiểm thử, và AutomationId thiết kế cho kiểm thử làm gỡ lỗi trong Live Inspect dễ hơn. Ngược lại, UI không xuất hiện trong cây UIA thì vô hình với cả kiểm thử lẫn công nghệ hỗ trợ. Khả năng tiếp cận và khả năng kiểm thử là hai mặt của cùng một đầu tư (“Kiểm thử tự động UI cho ứng dụng desktop Windows”).
flowchart TB
accTitle: Phần đền lẫn của khả năng tiếp cận và kiểm thử tự động UI
accDescr: Trình đọc màn hình và kiểm thử tự động UI như FlaUI được xây trên cùng UIA, nên Name và các mẫu bạn đặt dùng được từ cả hai, và UI không xuất hiện trong cây UIA thì vô hình từ phía nào
uia["Dọn cây UIA"] --> sr["Trình đọc màn hình đọc được"]
uia --> test["Dùng được trong kiểm thử tự động UI"]
sr -.-> both["Hai mặt của cùng một đầu tư"]
test -.-> both
hidden["UI không xuất hiện trong UIA"] -.-> invisible["Vô hình từ phía nào"]
Hình 17: Vì chúng ngồi trên cùng nền UIA, dọn cây UIA đền cả công nghệ hỗ trợ lẫn kiểm thử tự động UI.
9. Cách đặt ưu tiên — Đừng sửa mọi màn hình cùng lúc
Sửa một hệ thống lõi hàng trăm màn hình cùng lúc không thực tế cả về chi phí lẫn chất lượng. Cách chúng tôi khuyến nghị là ba tầng sau.
- Sửa từ các màn hình người dùng đó dùng trong việc. Điều chỉnh hợp lý là quá trình đáp cá nhân một yêu cầu từ người liên quan.1 Trước hết hãy để người đó thao tác việc thật với trình đọc màn hình, rồi cùng xác định chỗ họ kẹt. Trong nhiều trường hợp các màn hình dùng hàng ngày thu hẹp còn vài tới mười mấy, và các vấn đề chí tử trong đó (nút không tên, nút xác nhận không nhấn được từ bàn phím) giải được trong sửa vài ngày.
- Làm phát triển mới tuân chuẩn. Thêm danh sách kiểm Chương 8 vào Definition of Done, và xây màn hình mới được hỗ trợ từ đầu. Khác với sửa sau việc, mức tăng chi phí xây vào lúc thiết kế là nhỏ.
- Lan ngang bằng cách sửa điều khiển dùng chung. Nếu bạn triển khai AccessibleName mặc định hoặc AutomationPeer trên các phần nội bộ dùng chung như hộp thoại tìm, lưới, hoặc nhập ngày, nó có hiệu lực hàng loạt trên mọi màn hình dùng chúng. Đó là bước hiệu quả chi phí hơn nhiều so với đụng từng màn hình một.
flowchart TB
accTitle: Ba tầng ưu tiên sửa
accDescr: Sửa từ các màn hình người dùng dùng trong việc, làm phát triển mới tuân chuẩn bằng danh sách kiểm, và lan tới mọi màn hình bằng cách sửa điều khiển dùng chung
s1["1. Sửa từ các màn hình người dùng dùng"] --> s2["2. Việc mới tuân chuẩn"] --> s3["3. Lan ngang bằng điều khiển dùng chung"]
s3 -.-> all["Có hiệu lực hàng loạt trên mọi màn hình dùng chúng"]
Hình 18: Tiến không phải bằng sửa mọi màn hình cùng lúc mà theo ba tầng màn hình đang dùng, việc mới, và phần dùng chung.
Và bản ghi đối thoại quan trọng không kém phản hồi kỹ thuật. Điều chỉnh hợp lý là quá trình “đối thoại rồi điều chỉnh cá nhân”, không phải đáp đủ mọi yêu cầu. Cân một phương tiện thay với người đó (làm việc đó trên màn hình khác, chuẩn bị xuất CSV, bù bằng vận hành) rồi thỏa thuận, với lần sửa mà gánh quá nặng, cũng là kết quả chính đáng của đối thoại mang tính xây dựng.1 Ghi những gì đã được yêu cầu, những gì đã được đáp, và những gì được làm thành phương tiện thay trở thành bằng chứng thiện chí của tổ chức.
flowchart TB
accTitle: Luồng đối thoại mang tính xây dựng và bản ghi
accDescr: Đáp yêu cầu từ người khuyết tật qua đối thoại mang tính xây dựng; thực hiện lần sửa đáp được; với lần sửa mà gánh quá nặng, cân phương tiện thay với người đó rồi thỏa thuận; ghi những gì đã được yêu cầu, những gì đã được đáp, và những gì được làm thành phương tiện thay
req["Một yêu cầu"] --> talk["Đối thoại mang tính xây dựng"]
talk --> q{"Gánh có quá nặng?"}
q -->|Không| kaishu["Đáp bằng một lần sửa"]
q -->|Có| alt["Cân phương tiện thay rồi thỏa thuận"]
kaishu --> rec["Ghi lịch sử"]
alt --> rec
Hình 19: Trong đối thoại mang tính xây dựng bạn thỏa thuận với người đó về một lần sửa hoặc phương tiện thay, và để lịch sử đó trong bản ghi.
10. Tóm tắt
- Với Đạo luật Xóa bỏ Phân biệt đối xử với Người khuyết tật đã sửa có hiệu lực tháng 4 năm 2024, cung cấp điều chỉnh hợp lý trở thành nghĩa vụ với cả doanh nghiệp. Lĩnh vực việc làm đã là nghĩa vụ của người sử dụng lao động từ 2016 dưới Đạo luật Thúc đẩy Việc làm Người khuyết tật. Làm ứng dụng dễ dùng hơn từ trước là “cải thiện môi trường” (nghĩa vụ nỗ lực), và nó đã đi càng xa thì phản hồi cá nhân càng nhẹ.
- Tiêu chí kỹ thuật tập trung ở WCAG (JIS X 8341-3:2016), và cùng tư duy có thể áp dụng cho ứng dụng desktop qua WCAG2ICT.
- Trình đọc màn hình đọc ứng dụng qua UI Automation. Bộ ba cây UIA, thuộc tính (Name/ControlType/AutomationId), và mẫu điều khiển là nền.
- Ưu tiên cao nhất là Name. WinForms dùng AccessibleName và gắn Label với thứ tự tab; WPF dùng AutomationProperties.Name/LabeledBy; điều khiển tùy chỉnh dùng AutomationPeer.
- Đạt mọi chức năng chỉ từ bàn phím là tiêu chí thành công WCAG và, đồng thời, năng suất mọi người thao tác. Hãy dọn thứ tự tab, phím truy cập, và chỉ báo tiêu điểm.
- Ba nền tảng màu là tỷ lệ tương phản 4,5:1, màu không phải phương tiện duy nhất, và tôn trọng màu hệ thống trong chủ đề tương phản.
- Kết hợp xác minh bằng FastPass+Live Inspect trong Accessibility Insights và kiểm tay với Narrator/NVDA, rồi xây vào luồng phát triển như danh sách kiểm cho màn hình mới.
- Đừng sửa mọi màn hình cùng lúc; tiến theo thứ tự màn hình người dùng dùng → hỗ trợ chuẩn cho việc mới → lan ngang điều khiển dùng chung. Điều chỉnh hợp lý là quá trình đối thoại, và bản ghi lịch sử bảo vệ tổ chức.
Bước đầu chúng tôi khuyến nghị chọn một trong các màn hình chính của bạn, chạy FastPass trong Accessibility Insights for Windows, rồi đi việc chỉ bằng phím Tab. Trong ba mươi phút, vị trí hiện tại của chính ứng dụng bạn trở nên cụ thể đáng ngạc nhiên.
Bài viết liên quan
- Kiểm thử tự động UI cho ứng dụng desktop Windows — Cách UI Automation hoạt động và xây kiểm thử vững bằng FlaUI
- Thiết kế UX ứng dụng Windows — Ưu tiên theo môi trường sử dụng
- Hỗ trợ DPI cao trong WinForms — Vì sao UI mờ hoặc vỡ trên màn hình 4K, và các sửa thực tế
- Hỗ trợ DPI cao WPF — Vì sao vẫn mờ và lem dù ‘đáng lẽ đã nhận DPI’, và cách sửa
- Vì sao KomuraSoft xây website trên Hệ thống thiết kế Digital Agency — Chi phí thấp và chất lượng cao có thể cùng tồn tại
- Những cái bẫy phông chữ và ký tự Nhật — Xử lý JIS2004, IVS, và gaiji trong ứng dụng nghiệp vụ
Lĩnh vực tư vấn liên quan
KomuraSoft LLC đảm nhận sửa khả năng tiếp cận ứng dụng nghiệp vụ WinForms/WPF (hỗ trợ trình đọc màn hình, dọn thao tác bàn phím, hỗ trợ chủ đề tương phản), triển khai AutomationPeer trên điều khiển dùng chung, và tư vấn chẩn đoán hiện trạng cùng đặt ưu tiên với Accessibility Insights. Bắt đầu từ giai đoạn “chúng tôi muốn xác nhận một nhân viên có dùng được ứng dụng của chúng tôi bằng trình đọc màn hình không” cũng được.
Liên kết tham khảo
-
Cabinet Office, Leaflet “From 1 April 2024, the provision of reasonable accommodation became an obligation”. Về việc sửa đổi Reiwa 3 của Đạo luật Xóa bỏ Phân biệt đối xử với Người khuyết tật có hiệu lực ngày 1 tháng 4 Reiwa 6 và cung cấp điều chỉnh hợp lý bởi doanh nghiệp trở thành nghĩa vụ; về việc cung cấp điều chỉnh hợp lý là phản hồi, trong phạm vi không phải gánh nặng quá mức, trước bày tỏ ý định từ người khuyết tật; về tầm quan trọng của đối thoại mang tính xây dựng và từ chối một phía có thể cấu thành vi phạm nghĩa vụ; về “cải thiện môi trường”, các biện pháp cải thiện từ trước nhằm tới số người khuyết tật không xác định, là nghĩa vụ nỗ lực; và về việc làm cùng công việc tuân các điều khoản của Đạo luật Thúc đẩy Việc làm Người khuyết tật. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10
-
Ministry of Health, Labour and Welfare, The prohibition of discrimination against persons with disabilities in employment and the obligation to provide reasonable accommodation. Về đạo luật đã sửa về Thúc đẩy Việc làm Người khuyết tật có hiệu lực tháng 4 Heisei 28 buộc người sử dụng lao động cấm phân biệt khuyết tật trong việc làm và cung cấp điều chỉnh hợp lý trong phạm vi không phải gánh nặng quá mức; và về các tài liệu liên quan như hướng dẫn điều chỉnh hợp lý. ↩ ↩2 ↩3 ↩4
-
Web Accessibility Infrastructure Committee (WAIC), Understanding JIS X 8341-3:2016. Về việc JIS X 8341-3:2016 là chuẩn tương ứng của ISO/IEC 40500:2012, và thân chuẩn có cùng nội dung với WCAG 2.0; và về phạm vi nội dung web mà chuẩn giả định. ↩ ↩2
-
W3C, Guidance on Applying WCAG 2 to Non-Web Information and Communications Technologies (WCAG2ICT). Về W3C Group Note cho thấy cách áp dụng các nguyên tắc, hướng dẫn, và tiêu chí thành công của WCAG 2.0/2.1/2.2 cho tài liệu và phần mềm không-Web. ↩ ↩2
-
Microsoft Learn, UI Automation Specification. Về việc UI Automation cung cấp thông tin UI cho công nghệ hỗ trợ như trình đọc màn hình và cho phép thao tác bằng phương tiện khác đầu vào chuẩn; và về thành phần các phần tử UIA, cây, thuộc tính, mẫu điều khiển, loại điều khiển, và sự kiện. ↩ ↩2 ↩3
-
Microsoft Learn, WinForms: Setting the accessible name on a control. Về việc Text được tái dùng làm Name UIA trên một số điều khiển, trong khi ComboBox, ListBox, ListView, PictureBox, ProgressBar, TabControl, TextBox, TreeView và tương tự không tái dùng; về việc đặt điều khiển đích ngay sau TabIndex của Label để chữ Label được dùng làm Name; và về việc đặt AccessibleName tường minh cùng vấn đề chuỗi rỗng còn trong tệp designer. ↩ ↩2 ↩3 ↩4
-
W3C / Web Accessibility Infrastructure Committee (WAIC) translation, Web Content Accessibility Guidelines (WCAG) 2.1 Japanese translation. Về tiêu chí thành công 1.4.3 (Contrast (Minimum)) 4,5:1 cho chữ và 3:1 cho chữ lớn; về tiêu chí thành công 1.4.1 (Use of Color) không biến màu thành phương tiện nhìn duy nhất; và về tiêu chí thành công 2.1.1 (Keyboard) về khả năng thao tác bàn phím của mọi chức năng. ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
Microsoft Learn, Contrast themes. Về việc chủ đề tương phản dùng bảng màu hạn chế với tỷ lệ tương phản nói chung 7:1 trở lên; về việc chọn chủ đề dựng sẵn và sửa màu; và về việc tài nguyên lớp SystemColor được định nghĩa thành các cặp tiền cảnh/nền và theo chuyển chủ đề tự động. ↩ ↩2 ↩3
-
Microsoft Learn, Accessibility testing. Về ba kịch bản của Accessibility Insights for Windows — Live Inspect (xác nhận thuộc tính UIA bằng hover/tiêu điểm), FastPass (phát hiện vấn đề tác động cao trong dưới năm phút), và Troubleshooting — cùng khuyến nghị chuyển từ các công cụ kế thừa như Inspect và AccEvent. ↩ ↩2 ↩3
-
NVDA Japanese Team, NVDA Japanese edition. Về trình đọc màn hình Windows NVDA miễn phí, nguồn mở và việc cung cấp bản tiếng Nhật. ↩ ↩2
-
Microsoft Learn, Walkthrough: Creating an Accessible Windows-based Application. Về việc đặt một Label mô tả ở thứ tự tab ngay trước trường nhập; về phím truy cập qua & trong Text; về phán tương phản cao bằng SystemInformation.HighContrast và dùng SystemColors; về theo sự kiện UserPreferenceChanged; và về kết hợp tín hiệu nhìn với thông tin truyền bằng màu. ↩ ↩2 ↩3
-
Microsoft Learn, Providing Accessibility Information for Controls. Về các thuộc tính AccessibleName, AccessibleDescription, AccessibleRole, và AccessibleDefaultActionDescription của điều khiển WinForms cùng cách đặt chúng. ↩
-
Microsoft Learn, WPF: Setting the accessible name on an edit field. Về việc Text của TextBlock được tái dùng làm Name UIA, trong khi Text của TextBox được phơi như Value UIA; và về việc gắn TextBlock nhãn với TextBox qua AutomationProperties.LabeledBy, hoặc đặt AutomationProperties.Name. ↩
-
Microsoft Learn, UI Automation of a WPF Custom Control. Về việc điều khiển tùy chỉnh ghi đè OnCreateAutomationPeer và trả một lớp dẫn xuất AutomationPeer; về việc kế thừa lớp Peer tương ứng với điều khiển cơ sở; về việc cung cấp nhà cung cấp mẫu qua GetPattern; và về việc ghi đè từ phía XAML bằng thuộc tính AutomationProperties. ↩ ↩2
Bài viết liên quan
Các bài viết gần đây có cùng thẻ để tìm hiểu sâu hơn những chủ đề lân cận.
"Không phản hồi" thực sự là gì — Cách Windows quyết định ứng dụng đã treo, và cách thiết kế ứng dụng không treo
"Không phản hồi" của Windows là cơ chế trong đó hệ điều hành phán rằng một cửa sổ chưa lấy thông điệp trong 5 giây và thay nó bằng cửa sổ...
Clipboard và kéo thả hoạt động như thế nào — Xử lý đúng truyền dữ liệu OLE trong ứng dụng nghiệp vụ
Dán bảng Excel thì định dạng tan; đóng ứng dụng nguồn thì không còn dán được — cả hai đến từ việc clipboard đặt cùng nội dung ở nhiều địn...
Ứng dụng hỏng khi thức dậy từ ngủ — Sự kiện nguồn Windows và cách viết ứng dụng nghiệp vụ sống sót
Bạn mở laptop và kết nối của ứng dụng nghiệp vụ đã chết — nguyên nhân là thiết kế chưa tính đến ngủ. Bài viết này trình bày luồng thông b...
Cạm bẫy font và ký tự Nhật — xử lý JIS2004, IVS và gaiji trong ứng dụng nghiệp vụ
"Ký tự 葛 trông khác trên màn hình và trên biểu mẫu in." "Một ký tự trong tên người không hiển thị." Rắc rối ký tự trong hệ thống nghiệp v...
Bên trong ảo hóa Windows (Phần 3) — Máy ảo khởi động trong vài giây: Vì sao WSL2, Windows Sandbox và container lại nhẹ
Vì sao WSL2 và Windows Sandbox khởi động trong vài giây và cảm giác nhẹ đến vậy? Bài viết này giải thích các cơ chế, từ ảnh cơ sở động và...
Chủ đề liên quan
Các trang này đặt chủ đề trong bối cảnh rộng hơn của dịch vụ và quyết định.
Chủ đề kỹ thuật Windows
Cổng vào phát triển Windows, điều tra lỗi và khai thác tài sản hiện có.
Luồng UI và bộ định thời
Luồng UI của WPF / WinForms, luồng bất đồng bộ, Dispatcher và thiết kế bộ định thời.
Dịch vụ liên quan đến chủ đề này
Bài viết liên quan trực tiếp đến các dịch vụ sau.
Phát triển ứng dụng Windows
Ứng dụng nghiệp vụ, tích hợp thiết bị và công cụ liên lạc, từ yêu cầu đến phát triển.
Câu hỏi thường gặp
Các câu hỏi thường gặp khi tư vấn về chủ đề của bài viết.
- Hỗ trợ khả năng tiếp cận cho ứng dụng nghiệp vụ có bắt buộc theo luật không?
- Sửa đổi 2021 của Đạo luật Xóa bỏ Phân biệt đối xử với Người khuyết tật có hiệu lực ngày 1 tháng 4 năm 2024, và việc cung cấp điều chỉnh hợp lý cho người khuyết tật trở thành nghĩa vụ với cả doanh nghiệp. Điều chỉnh hợp lý là phản hồi mà, khi người khuyết tật đưa yêu cầu, gỡ một rào cản cá nhân trong phạm vi không phải gánh nặng quá mức; làm ứng dụng dễ dùng hơn từ trước được định vị như nghĩa vụ nỗ lực gọi là "cải thiện môi trường". Việc làm, như quan hệ giữa nhân viên và công ty, không thuộc đạo luật đó mà thuộc Đạo luật Thúc đẩy Việc làm Người khuyết tật, vốn đã buộc người sử dụng lao động cung cấp điều chỉnh hợp lý từ sửa đổi có hiệu lực tháng 4 năm 2016. Nói cách khác, tình huống "một nhân viên không dùng được ứng dụng nghiệp vụ" đã nằm trong phạm vi nghĩa vụ từ lâu. Đi tới đâu trong từng vụ phụ thuộc tình huống cá nhân, nên bạn xác nhận nguồn gốc từ Văn phòng Nội các và Bộ Y tế, Lao động và Phúc lợi rồi quyết qua đối thoại với người liên quan.
- Trình đọc màn hình đọc ứng dụng desktop Windows thế nào?
- Các trình đọc màn hình như Narrator và NVDA đọc UI của ứng dụng qua một nền tảng khả năng tiếp cận gọi là UI Automation (UIA). Phía ứng dụng phơi các phần tử trên màn hình trong cấu trúc gọi là cây UIA; mỗi phần tử có thuộc tính như Name (mục đích) và ControlType (loại), cùng các mẫu điều khiển như Invoke (nhấn) và Value (giá trị). Trình đọc màn hình công bố thông tin này thành "nút Xác nhận đơn" và thao tác qua các mẫu. Các điều khiển chuẩn WinForms và WPF có cơ chế này từ đầu, nên việc chính của nhà phát triển là không để Name trống, làm UI thao tác được từ bàn phím, và triển khai thông tin trên điều khiển tùy chỉnh.
- Trên một ứng dụng WinForms sẵn có, chúng tôi nên bắt đầu từ đâu?
- Đường ngắn nhất là chạy FastPass trong Accessibility Insights for Windows trên màn hình đích và lập danh sách các điều khiển Name trống cùng vấn đề thứ tự tab. Sửa bắt đầu bằng đặt AccessibleName trên các nút chỉ-biểu tượng, gắn một Label ở thứ tự tab ngay trước một trường nhập, và dọn TabIndex cho khớp thứ tự nhìn. Rồi khởi động Narrator hoặc NVDA và đi một thao tác nghiệp vụ thật mà không nhìn màn hình, rồi xác nhận chỗ bạn kẹt. Bạn không cần sửa mọi màn hình cùng lúc; bắt đầu từ các màn hình mà ai đó thực sự dùng, và làm màn hình mới tuân chuẩn bằng danh sách kiểm, là thực tế.
- Chúng tôi nên làm gì cho hỗ trợ tương phản cao (chủ đề tương phản)?
- Đường cơ sở là không gắn cứng màu và tôn trọng màu hệ thống. Trong WinForms, để ForeColor/BackColor ở mặc định hoặc dùng SystemColors, phán trạng thái bằng SystemInformation.HighContrast, và theo một lần chuyển bằng sự kiện UserPreferenceChanged. Trong WPF và WinUI cũng vậy, nếu bạn tham chiếu tài nguyên lớp SystemColors, bạn theo chuyển chủ đề tự động. Đồng thời, hãy thôi truyền thông tin "chỉ bằng màu" — hiện lỗi chỉ bằng đỏ — và kết hợp với biểu tượng hoặc lời. Ngay cả trong chủ đề thường, lấy tiêu chí WCAG tỷ lệ tương phản chữ 4,5:1 trở lên làm hướng dẫn cũng làm UI dễ đọc hơn với sàn xưởng tối và người dùng lớn tuổi.
- Hỗ trợ khả năng tiếp cận có giúp kiểm thử tự động UI không?
- Có. Các công cụ kiểm thử tự động UI như FlaUI được xây trên cùng UI Automation mà trình đọc màn hình dùng. Name, ControlType và các mẫu điều khiển bạn đặt cho khả năng tiếp cận dùng được nguyên si từ mã kiểm thử, và một AutomationId thiết kế cho kiểm thử làm ổn định nhận diện phần tử. Ngược lại, một UI vẽ tùy chỉnh không xuất hiện trong cây UIA thì vô hình với cả trình đọc màn hình lẫn kiểm thử. Khả năng tiếp cận và kiểm thử tự động là đầu tư vào cùng một nền, nên đặt cái nào cũng hạ chi phí cái kia.