Bagikan melalui


Aksesibilitas keyboard

Membangun aksesibilitas keyboard (untuk perangkat keras emulasi tradisional, dimodifikasi, atau keyboard) ke dalam aplikasi Anda, memberi pengguna yang buta, memiliki penglihatan rendah, disabilitas motorik, atau memiliki sedikit atau tidak menggunakan tangan mereka, kemampuan untuk menavigasi dan menggunakan fungsionalitas penuh aplikasi Anda. Selain itu, pengguna tanpa disabilitas mungkin memilih keyboard untuk navigasi karena preferensi atau efisiensi.

Jika aplikasi Anda tidak menyediakan akses keyboard yang baik, pengguna yang buta atau mengalami masalah mobilitas mungkin mengalami kesulitan menggunakan aplikasi Anda.

Navigasi keyboard di antara elemen UI

Untuk berinteraksi dengan kontrol menggunakan keyboard, kontrol harus memiliki fokus. Untuk menerima fokus (tanpa menggunakan penunjuk), kontrol harus dapat diakses melalui navigasi tab. Secara default, urutan tab kontrol sama dengan urutan ditambahkan ke permukaan desain, dideklarasikan dalam XAML, atau ditambahkan secara terprogram ke kontainer.

Biasanya, urutan tab default didasarkan pada bagaimana kontrol didefinisikan dalam XAML, terutama karena itu adalah urutan di mana kontrol dilalui oleh pembaca layar. Namun, urutan default tidak selalu sesuai dengan urutan visual. Posisi tampilan aktual mungkin bergantung pada kontainer tata letak induk dan berbagai properti elemen turunan yang dapat memengaruhi tata letak.

Untuk memastikan aplikasi Anda memiliki urutan tab yang optimal, uji sendiri perilakunya. Jika Anda menggunakan kisi atau tabel untuk tata letak Anda, urutan pengguna mungkin membaca layar versus urutan tab bisa sangat berbeda. Ini tidak selalu menjadi masalah, tetapi pastikan untuk menguji fungsionalitas aplikasi Anda melalui sentuhan dan keyboard untuk memverifikasi bahwa UI Anda dioptimalkan untuk kedua metode input.

Anda dapat membuat urutan tab cocok dengan urutan visual dengan menyesuaikan XAML atau menimpa urutan tab default. Contoh berikut menunjukkan cara menggunakan properti TabIndex dengan tata letak Kisi yang menggunakan navigasi tab kolom-pertama.

<Grid>
  <Grid.RowDefinitions>...</Grid.RowDefinitions>
  <Grid.ColumnDefinitions>...</Grid.ColumnDefinitions>

  <TextBlock Grid.Column="1" HorizontalAlignment="Center">Groom</TextBlock>
  <TextBlock Grid.Column="2" HorizontalAlignment="Center">Bride</TextBlock>

  <TextBlock Grid.Row="1">First name</TextBlock>
  <TextBox x:Name="GroomFirstName" Grid.Row="1" Grid.Column="1" TabIndex="1"/>
  <TextBox x:Name="BrideFirstName" Grid.Row="1" Grid.Column="2" TabIndex="3"/>

  <TextBlock Grid.Row="2">Last name</TextBlock>
  <TextBox x:Name="GroomLastName" Grid.Row="2" Grid.Column="1" TabIndex="2"/>
  <TextBox x:Name="BrideLastName" Grid.Row="2" Grid.Column="2" TabIndex="4"/>
</Grid>

Dalam beberapa kasus, Anda mungkin ingin mengecualikan kontrol tertentu dari urutan tab. Ini biasanya dicapai dengan membuat kontrol noninteraktif dengan mengatur properti IsEnabled-nya ke false. Kontrol yang dinonaktifkan secara otomatis dikecualikan dari urutan tab.

Jika Anda ingin mengecualikan kontrol interaktif dari urutan tab, Anda dapat mengatur properti IsTabStop ke false.

Secara default, elemen UI yang mendukung fokus biasanya disertakan dalam urutan tab. Beberapa pengecualian untuk ini termasuk jenis tampilan teks tertentu (seperti RichTextBlock) yang mendukung fokus untuk pemilihan teks dan akses clipboard tetapi tidak dalam urutan tab karena merupakan elemen teks statis. Kontrol ini tidak interaktif secara konvensional (tidak dapat dipanggil, dan tidak memerlukan input teks, tetapi mendukung pola Kontrol teks yang mendukung penemuan dan penyesuaian titik pilihan dalam teks). Kontrol teks masih akan terdeteksi oleh teknologi bantuan, dan dibacakan dengan keras di pembaca layar, tetapi itu bergantung pada teknik selain urutan tab.

Baik Anda menyesuaikan nilai TabIndex atau menggunakan urutan default, aturan ini berlaku:

  • Jika TabIndex tidak diatur pada elemen, nilai defaultnya adalah Int32.MaxValue dan urutan tab didasarkan pada urutan deklarasi dalam koleksi XAML atau anak.
  • Jika TabIndex diatur pada elemen:
    • Elemen UI dengan TabIndex sama dengan 0 ditambahkan ke urutan tab berdasarkan urutan deklarasi dalam koleksi XAML atau turunan.
    • Elemen UI dengan TabIndex yang lebih besar dari 0 ditambahkan ke urutan tab berdasarkan nilai TabIndex.
    • Elemen UI dengan TabIndex kurang dari 0 ditambahkan ke urutan tab dan muncul sebelum nilai nol.

Cuplikan kode berikut menunjukkan kumpulan elemen dengan berbagai pengaturan TabIndex (B diberi nilai Int32.MaxValue, atau 2.147.483.647).

<StackPanel Background="#333">
  <StackPanel Background="#FF33FF">
    <Button>A</Button>
    <Button TabIndex="2147483647">B</Button>
    <Button>C</Button>
  </StackPanel>
  <StackPanel Background="#33FFFF">
    <Button TabIndex="1">D</Button>
    <Button TabIndex="1">E</Button>
    <Button TabIndex="0">F</Button>
  </StackPanel>
</StackPanel>

Ini menghasilkan urutan tab berikut:

  1. F
  2. D
  3. E
  4. A
  5. B
  6. C

Navigasi keyboard antar panel aplikasi dengan F6

Panel aplikasi adalah area logis UI terkait yang menonjol dalam jendela aplikasi (misalnya, panel Microsoft Edge menyertakan bilah alamat, bilah marka buku, bilah tab, dan panel konten). Tombol F6 dapat digunakan untuk menavigasi di antara panel ini, di mana grup elemen turunan kemudian dapat diakses menggunakan navigasi keyboard standar.

Meskipun navigasi keyboard dapat menyediakan UI yang sesuai aksesibel, membuat UI yang dapat diakses sering memerlukan beberapa langkah lagi. Biasanya, ini termasuk:

  • Mendengarkan F6 untuk menavigasi di antara bagian penting UI Anda.
  • Menambahkan pintasan keyboard untuk tindakan umum di UI Anda.
  • Menambahkan kunci akses ke kontrol penting di UI Anda.

Lihat Pintasan keyboard di bawah ini dan Tombol akses untuk panduan selengkapnya tentang menerapkan pintasan dan tombol akses.

Optimalkan untuk F6

F6 memungkinkan pengguna keyboard secara efisien menavigasi antar panel UI tanpa melakukan tab melalui ratusan kontrol yang berpotensi.

Misalnya, F6 dalam siklus Microsoft Edge antara bilah alamat, bilah marka buku, bilah tab, dan panel konten. Karena halaman web berpotensi memiliki ratusan kontrol yang dapat ditabel, F6 dapat memudahkan pengguna keyboard untuk mencapai bilah tab dan bilah alamat tanpa menggunakan pintasan khusus aplikasi.

Siklus tab F6 juga dapat secara longgar sesuai dengan landmark atau judul dalam konten, meskipun tidak perlu cocok persis. F6 harus fokus pada wilayah besar dan berbeda di UI Anda, sedangkan landmark bisa lebih terperinci. Misalnya, Anda dapat menandai bilah aplikasi dan kotak pencariannya sebagai landmark, tetapi hanya menyertakan bilah aplikasi itu sendiri dalam siklus F6.

Penting

Anda harus menerapkan navigasi F6 di aplikasi karena tidak didukung secara asli.

Jika memungkinkan, wilayah dalam siklus F6 harus memiliki nama yang dapat diakses: baik melalui landmark atau dengan menambahkan AutomationProperties.Name secara manual ke elemen "root" wilayah.

Shift-F6 harus bersepeda ke arah yang berlawanan.

Navigasi keyboard dalam elemen UI

Untuk kontrol komposit, penting untuk memastikan navigasi dalam yang tepat di antara elemen yang terkandung. Kontrol komposit dapat mengelola elemen turunan yang saat ini aktif untuk mengurangi overhead memiliki semua elemen anak yang mendukung fokus. Kontrol komposit disertakan dalam urutan tab dan menangani peristiwa navigasi keyboard itu sendiri. Banyak kontrol komposit sudah memiliki beberapa logika navigasi dalam yang terpasang dalam penanganan peristiwa mereka. Misalnya, traversal panah-kunci item diaktifkan secara default pada kontrol ListView, GridView, ListBox, dan FlipView.

Alternatif keyboard untuk tindakan penunjuk dan peristiwa untuk elemen kontrol tertentu

Elemen UI yang dapat diklik juga harus dipanggil melalui keyboard. Untuk menggunakan keyboard dengan elemen UI, elemen harus memiliki fokus (hanya kelas yang berasal dari fokus dukungan Kontrol dan navigasi tab).

Untuk elemen UI yang dapat dipanggil, terapkan penanganan aktivitas keyboard untuk tombol Spacebar dan Enter. Ini memastikan dukungan aksesibilitas keyboard dasar dan memungkinkan pengguna menjangkau semua elemen UI interaktif dan mengaktifkan fungsionalitas hanya dengan menggunakan keyboard.

Jika elemen tidak mendukung fokus, Anda dapat membuat kontrol kustom Anda sendiri. Dalam hal ini, untuk mengaktifkan fokus, Anda harus mengatur properti IsTabStop ke true dan Anda harus memberikan indikasi visual status visual yang berfokus dengan indikator fokus.

Namun, dapat lebih mudah menggunakan komposisi kontrol sehingga dukungan untuk tab berhenti, fokus, dan rekan dan pola Microsoft UI Automation ditangani oleh kontrol tempat Anda memilih untuk menyusun konten Anda. Misalnya, alih-alih menangani peristiwa yang ditekan penunjuk pada Gambar, bungkus elemen tersebut dalam Tombol untuk mendapatkan penunjuk, keyboard, dan dukungan fokus.

<!--Don't do this.-->
<Image Source="sample.jpg" PointerPressed="Image_PointerPressed"/>

<!--Do this instead.-->
<Button Click="Button_Click"><Image Source="sample.jpg"/></Button>

Pintasan keyboard

Selain menerapkan navigasi dan aktivasi keyboard, ada baiknya juga menerapkan pintasan keyboard seperti akselerator keyboard dan tombol akses untuk fungsionalitas penting atau sering digunakan.

Pintasan adalah kombinasi keyboard yang menyediakan cara yang efisien bagi pengguna untuk mengakses fungsionalitas aplikasi. Ada dua jenis pintasan:

  • Akselerator adalah pintasan yang memanggil perintah aplikasi. Aplikasi Anda mungkin atau mungkin tidak menyediakan UI tertentu yang sesuai dengan perintah. Akselerator biasanya terdiri dari tombol Ctrl ditambah kunci huruf.
  • Kunci akses adalah pintasan yang mengatur fokus ke UI tertentu di aplikasi Anda. Kunci akses yang khas terdiri dari kunci Alt ditambah kunci huruf.

Selalu berikan cara mudah bagi pengguna yang mengandalkan pembaca layar dan teknologi bantuan lainnya untuk menemukan kunci pintasan aplikasi Anda. Komunikasikan kunci pintasan dengan menggunakan tipsalat, nama yang dapat diakses, deskripsi yang dapat diakses, atau beberapa bentuk komunikasi di layar lainnya. Minimal, kunci pintasan harus didokumenkan dengan baik di konten Bantuan aplikasi Anda.

Anda dapat mendokumentasikan kunci akses melalui pembaca layar dengan mengatur properti terpasang AutomationProperties.AccessKey ke string yang menjelaskan kunci pintasan. Ada juga properti terlampir AutomationProperties.AcceleratorKey untuk mendokumentasikan kunci pintasan non-mnemonik, meskipun pembaca layar umumnya memperlakukan kedua properti dengan cara yang sama. Coba dokumentasikan kunci pintasan dengan beberapa cara, menggunakan tipsalat, properti otomatisasi, dan dokumentasi Bantuan tertulis.

Contoh berikut menunjukkan cara mendokumen kunci pintasan untuk tombol putar media, jeda, dan hentikan.

<Grid KeyDown="Grid_KeyDown">

  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>

  <MediaElement x:Name="DemoMovie" Source="xbox.wmv"
    Width="500" Height="500" Margin="20" HorizontalAlignment="Center" />

  <StackPanel Grid.Row="1" Margin="10"
    Orientation="Horizontal" HorizontalAlignment="Center">

    <Button x:Name="PlayButton" Click="MediaButton_Click"
      ToolTipService.ToolTip="Shortcut key: Ctrl+P"
      AutomationProperties.AcceleratorKey="Control P">
      <TextBlock>Play</TextBlock>
    </Button>

    <Button x:Name="PauseButton" Click="MediaButton_Click"
      ToolTipService.ToolTip="Shortcut key: Ctrl+A"
      AutomationProperties.AcceleratorKey="Control A">
      <TextBlock>Pause</TextBlock>
    </Button>

    <Button x:Name="StopButton" Click="MediaButton_Click"
      ToolTipService.ToolTip="Shortcut key: Ctrl+S"
      AutomationProperties.AcceleratorKey="Control S">
      <TextBlock>Stop</TextBlock>
    </Button>
  </StackPanel>
</Grid>

Penting

Mengatur AutomationProperties.AcceleratorKey atau AutomationProperties.AccessKey tidak mengaktifkan fungsionalitas keyboard. Ini hanya menunjukkan kunci apa yang harus digunakan untuk kerangka kerja Automation UI dan kemudian dapat diteruskan ke pengguna melalui teknologi bantuan.

Penanganan kunci diimplementasikan dalam code-behind, bukan XAML. Anda masih perlu melampirkan handler untuk peristiwa KeyDown atau KeyUp pada kontrol yang relevan untuk benar-benar menerapkan perilaku pintasan keyboard di aplikasi Anda. Selain itu, dekorasi teks garis bawah untuk kunci akses tidak disediakan secara otomatis. Anda harus secara eksplisit menggaris bawahi teks untuk kunci tertentu dalam mnemonic Anda sebagai pemformatan Garis Bawah sebaris jika Anda ingin menampilkan teks bergaris bawah di UI.

Untuk kesederhanaan, contoh sebelumnya menghilangkan penggunaan sumber daya untuk string seperti "Ctrl+A". Namun, Anda juga harus mempertimbangkan kunci pintasan selama pelokalan. Melokalisasi kunci pintasan relevan karena pilihan kunci yang akan digunakan sebagai kunci pintasan biasanya bergantung pada label teks yang terlihat untuk elemen tersebut.

Untuk panduan selengkapnya tentang menerapkan kunci pintasan, lihat Kunci pintasan di Panduan Interaksi Pengalaman Pengguna Windows.

Menerapkan penanganan aktivitas utama

Peristiwa input (seperti peristiwa utama) menggunakan konsep peristiwa yang disebut peristiwa yang dirutekan. Peristiwa yang dirutekan dapat menggelegak melalui elemen anak dari kontrol komposit induk, sehingga kontrol induk dapat menangani peristiwa untuk beberapa elemen anak. Model kejadian ini nyaman untuk menentukan tindakan kunci pintasan untuk kontrol yang berisi beberapa elemen anak, yang tidak satu pun dapat memiliki fokus atau menjadi bagian dari urutan tab.

Misalnya kode yang menunjukkan cara menulis penanganan aktivitas utama yang menyertakan pemeriksaan pengubah seperti tombol Ctrl, lihat Interaksi keyboard.

Navigasi keyboard untuk kontrol kustom

Sebaiknya gunakan tombol panah sebagai pintasan keyboard untuk menavigasi di antara elemen anak jika elemen anak memiliki hubungan spasial satu sama lain. Jika simpul tampilan pohon memiliki sub-elemen terpisah untuk menangani aktivasi expand-collapse dan node, gunakan tombol panah kiri dan kanan untuk menyediakan fungsionalitas expand-collapse keyboard. Jika Anda memiliki kontrol berorientasi yang mendukung traversal arah dalam konten kontrol, gunakan tombol panah yang sesuai.

Umumnya Anda menerapkan penanganan kunci kustom untuk kontrol kustom dengan menyertakan penimpaan metode OnKeyDown dan OnKeyUp sebagai bagian dari logika kelas.

Contoh status visual untuk indikator fokus

Seperti disebutkan sebelumnya, kontrol kustom apa pun yang mendukung fokus harus memiliki indikator fokus visual. Biasanya, indikator fokus tersebut hanyalah persegi panjang yang menguraikan persegi panjang batas kontrol. Persegi panjang untuk fokus visual adalah elemen serekan ke komposisi kontrol lainnya dalam templat kontrol, tetapi awalnya diatur dengan nilai Visibilitas Diciutkan karena kontrol belum difokuskan. Ketika kontrol mendapatkan fokus, status visual dipanggil yang secara khusus mengatur Visibilitas visual fokus ke Terlihat. Setelah fokus dipindahkan ke tempat lain, status visual lain dipanggil, dan Visibilitas menjadi Diciutkan.

Semua kontrol XAML yang dapat difokuskan menampilkan indikator fokus visual yang sesuai saat difokuskan. Pengguna yang dipilih mereka juga dapat memengaruhi tampilan indikator (terutama jika pengguna menggunakan mode kontras tinggi). Jika Anda menggunakan kontrol XAML di UI Anda (dan tidak mengganti templat kontrol), Anda tidak perlu melakukan apa pun tambahan untuk mendapatkan indikator fokus visual default. Namun, jika Anda berniat untuk mengintemplasi ulang kontrol, atau jika Anda ingin tahu tentang bagaimana kontrol XAML memberikan indikator fokus visual mereka, sisa bagian ini menjelaskan bagaimana hal ini dilakukan di XAML dan logika kontrol.

Berikut adalah beberapa contoh XAML yang berasal dari templat XAML default untuk Tombol.

XAML

<ControlTemplate TargetType="Button">
...
    <Rectangle
      x:Name="FocusVisualWhite"
      IsHitTestVisible="False"
      Stroke="{ThemeResource FocusVisualWhiteStrokeThemeBrush}"
      StrokeEndLineCap="Square"
      StrokeDashArray="1,1"
      Opacity="0"
      StrokeDashOffset="1.5"/>
    <Rectangle
      x:Name="FocusVisualBlack"
      IsHitTestVisible="False"
      Stroke="{ThemeResource FocusVisualBlackStrokeThemeBrush}"
      StrokeEndLineCap="Square"
      StrokeDashArray="1,1"
      Opacity="0"
      StrokeDashOffset="0.5"/>
...
</ControlTemplate>

Sejauh ini hanya komposisi. Untuk mengontrol visibilitas indikator fokus, Anda menentukan status visual yang mengalihkan properti Visibilitas . Ini dilakukan menggunakan properti terlampir VisualStateManager dan VisualStateManager.VisualStateGroups, seperti yang diterapkan pada elemen akar yang menentukan komposisi.

<ControlTemplate TargetType="Button">
  <Grid>
    <VisualStateManager.VisualStateGroups>
       <!--other visual state groups here-->
       <VisualStateGroup x:Name="FocusStates">
         <VisualState x:Name="Focused">
           <Storyboard>
             <DoubleAnimation
               Storyboard.TargetName="FocusVisualWhite"
               Storyboard.TargetProperty="Opacity"
               To="1" Duration="0"/>
             <DoubleAnimation
               Storyboard.TargetName="FocusVisualBlack"
               Storyboard.TargetProperty="Opacity"
               To="1" Duration="0"/>
         </VisualState>
         <VisualState x:Name="Unfocused" />
         <VisualState x:Name="PointerFocused" />
       </VisualStateGroup>
     <VisualStateManager.VisualStateGroups>
<!--composition is here-->
   </Grid>
</ControlTemplate>

Perhatikan bagaimana hanya salah satu status bernama yang menyesuaikan Visibilitas secara langsung sedangkan yang lain tampaknya kosong. Dengan status visual, segera setelah kontrol menggunakan status lain dari VisualStateGroup yang sama, animasi apa pun yang diterapkan oleh status sebelumnya segera dibatalkan. Karena Visibilitas default dari komposisi Diciutkan, persegi panjang tidak akan muncul. Logika kontrol mengontrol ini dengan mendengarkan peristiwa fokus seperti GotFocus dan mengubah status dengan GoToState. Seringkali ini sudah ditangani untuk Anda jika Anda menggunakan kontrol default atau menyesuaikan berdasarkan kontrol yang sudah memiliki perilaku tersebut.

Aksesibilitas keyboard dan perangkat tanpa keyboard perangkat keras

Beberapa perangkat tidak memiliki keyboard perangkat keras khusus dan mengandalkan Panel Input Lunak (SIP) sebagai gantinya. Pembaca layar dapat membaca input teks dari SIP Teks dan pengguna dapat menemukan di mana jari mereka berada karena pembaca layar dapat mendeteksi bahwa pengguna memindai kunci, dan membacakan nama kunci yang dipindai dengan keras. Selain itu, beberapa konsep aksesibilitas berorientasi keyboard dapat dipetakan ke perilaku teknologi bantuan terkait yang tidak menggunakan keyboard sama sekali. Misalnya, meskipun SIP tidak akan menyertakan tombol Tab, Narator mendukung gerakan sentuh yang setara dengan menekan tombol Tab, sehingga memiliki urutan tab yang berguna melalui kontrol di UI masih kotor untuk aksesibilitas. Narator juga mendukung banyak gerakan sentuh lainnya, termasuk tombol panah untuk menavigasi dalam kontrol kompleks (lihat Perintah keyboard Narator dan gerakan sentuh).

Contoh

Tip

Aplikasi Galeri WinUI 3 mencakup contoh interaktif dari sebagian besar kontrol, fitur, dan fungsi WinUI 3. Dapatkan aplikasi dari Microsoft Store atau dapatkan kode sumber di GitHub