Aksesibilitas keyboard

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

Navigasi keyboard di antara elemen UI

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

Dalam kebanyakan kasus, urutan default berdasarkan bagaimana Anda menentukan kontrol di XAML adalah urutan terbaik, terutama karena itu adalah urutan di mana kontrol dibaca oleh pembaca layar. Namun, urutan default tidak selalu sesuai dengan urutan visual. Posisi tampilan aktual mungkin bergantung pada kontainer tata letak induk dan properti tertentu yang dapat Anda atur pada elemen anak untuk memengaruhi tata letak. Untuk memastikan aplikasi Anda memiliki urutan tab yang baik, uji perilaku ini sendiri. Terutama jika Anda memiliki metafora kisi atau metafora tabel untuk tata letak Anda, urutan di mana pengguna mungkin membaca versus urutan tab bisa berakhir berbeda. Itu tidak selalu menjadi masalah dalam dan dari dirinya sendiri. Tetapi pastikan untuk menguji fungsionalitas aplikasi Anda baik sebagai UI yang dapat disentuh maupun sebagai UI yang dapat diakses keyboard dan verifikasi bahwa UI Anda masuk akal.

Anda dapat membuat urutan tab cocok dengan urutan visual dengan menyesuaikan XAML. Atau Anda dapat mengganti urutan tab default dengan mengatur properti TabIndex , seperti yang diperlihatkan dalam contoh tata letak Kisi berikut yang menggunakan navigasi tab kolom-pertama.

XAML

<!--Custom tab order.-->
<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>

Anda mungkin ingin mengecualikan kontrol dari urutan tab. Anda biasanya melakukan ini hanya dengan membuat kontrol noninteraktif, misalnya dengan mengatur properti IsEnabled-nya ke false. Kontrol yang dinonaktifkan secara otomatis dikecualikan dari urutan tab. Tetapi terkadang Anda mungkin ingin mengecualikan kontrol dari urutan tab meskipun tidak dinonaktifkan. Dalam hal ini, Anda dapat mengatur properti IsTabStop ke false.

Elemen apa pun yang dapat memiliki fokus biasanya berada dalam urutan tab secara default. Pengecualian untuk ini adalah bahwa jenis tampilan teks tertentu seperti RichTextBlock dapat memiliki fokus sehingga dapat diakses oleh clipboard untuk pemilihan teks; namun, elemen tersebut tidak berada dalam urutan tab karena tidak diharapkan elemen teks statis berada dalam urutan tab. Mereka 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). Teks seharusnya tidak memiliki konnotasi yang mengatur fokus ke teks tersebut akan mengaktifkan beberapa tindakan yang mungkin. Elemen teks masih akan terdeteksi oleh teknologi bantuan, dan dibacakan dengan keras di pembaca layar, tetapi itu bergantung pada teknik selain menemukan elemen-elemen tersebut dalam urutan tab praktis.

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

  • Jika TabIndex tidak diatur pada elemen, nilai default yang digunakan 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. Ini berpotensi berbeda dari penanganan HTML dari atribut tabindex-nya (dan tabindex negatif tidak didukung dalam spesifikasi HTML yang lebih lama).

Misalnya, cuplikan berikut menunjukkan kumpulan elemen dengan pengaturan TabIndex yang bervariasi (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 dalam elemen UI

Untuk elemen komposit, penting untuk memastikan navigasi dalam yang tepat di antara elemen yang terkandung. Elemen komposit dapat mengelola anak aktifnya saat ini untuk mengurangi overhead memiliki semua elemen anak yang dapat memiliki fokus. Elemen komposit seperti itu 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 kontrol. 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

Pastikan bahwa elemen UI yang dapat diklik juga dapat dipanggil dengan menggunakan keyboard. Untuk menggunakan keyboard dengan elemen UI, elemen harus memiliki fokus. Hanya kelas yang berasal dari kontrol mendukung fokus dan navigasi tab.

Untuk elemen UI yang dapat dipanggil, terapkan penanganan aktivitas keyboard untuk tombol Spacebar dan Enter. Ini membuat dukungan aksesibilitas keyboard dasar selesai dan memungkinkan pengguna untuk menyelesaikan skenario aplikasi dasar hanya dengan menggunakan keyboard; artinya, pengguna dapat menjangkau semua elemen UI interaktif dan mengaktifkan fungsionalitas default.

Dalam kasus di mana elemen yang ingin Anda gunakan di UI tidak dapat memiliki fokus, Anda dapat membuat kontrol kustom Anda sendiri. Anda harus mengatur properti IsTabStop ke true untuk mengaktifkan fokus dan Anda harus memberikan indikasi visual status terfokus dengan membuat status visual yang menghias UI dengan indikator fokus. Namun, seringkali lebih mudah untuk menggunakan komposisi kontrol sehingga dukungan untuk tab berhenti, fokus, dan rekan dan pola Microsoft UI Automation ditangani oleh kontrol di mana Anda memilih untuk menyusun konten Anda.

Misalnya, alih-alih menangani peristiwa yang ditekan penunjuk pada Gambar, Anda dapat membungkus elemen tersebut dalam Tombol untuk mendapatkan penunjuk, keyboard, dan dukungan fokus.

XAML

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

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

Pintasan papan ketik

Selain menerapkan navigasi dan aktivasi keyboard untuk aplikasi Anda, ini adalah praktik yang baik untuk menerapkan pintasan untuk fungsionalitas aplikasi Anda. Navigasi tab menyediakan tingkat dukungan keyboard dasar yang baik, tetapi dengan formulir kompleks Anda mungkin juga ingin menambahkan dukungan untuk tombol pintasan. Ini dapat membuat aplikasi Anda lebih efisien untuk digunakan, bahkan untuk orang-orang yang menggunakan keyboard dan perangkat penunjuk.

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

  • Kunci akses adalah pintasan ke sepotong UI di aplikasi Anda. Kunci akses terdiri dari kunci Alt ditambah kunci huruf.
  • Kunci akselerator adalah pintasan ke perintah aplikasi. Aplikasi Anda mungkin atau mungkin tidak memiliki UI yang sesuai persis dengan perintah. Tombol akselerator terdiri dari tombol Ctrl ditambah kunci huruf.

Sangat penting bahwa Anda menyediakan 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 dicocokkan dengan baik di konten Bantuan aplikasi Anda.

Anda dapat mendokumentasikan kunci akses melalui pembaca layar dengan mengatur properti terlampir 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 berbagai cara, menggunakan tipsalat, properti otomatisasi, dan dokumentasi Bantuan tertulis.

Contoh berikut menunjukkan cara men dokumentasikan tombol pintasan untuk tombol putar media, jeda, dan hentikan.

XAML

<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 melaporkan ke kerangka kerja Automation UI kunci apa yang harus digunakan, sehingga informasi tersebut dapat diteruskan kepada pengguna melalui teknologi bantuan. Implementasi untuk penanganan kunci masih perlu dilakukan dalam kode, bukan XAML. Anda masih perlu melampirkan handler untuk peristiwa KeyDown atau KeyUp pada kontrol yang relevan untuk benar-benar mengimplementasikan 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 tombol pintasan relevan karena pilihan kunci yang akan digunakan sebagai kunci pintasan biasanya tergantung pada label teks yang terlihat untuk elemen .

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 bergelembung melalui elemen anak dari kontrol yang disusupi, sehingga induk kontrol umum dapat menangani peristiwa untuk beberapa elemen anak. Model kejadian ini nyaman untuk menentukan tindakan kunci pintasan untuk kontrol yang berisi beberapa bagian komposit yang menurut desain tidak 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

Kami merekomendasikan penggunaan tombol panah sebagai pintasan keyboard untuk menavigasi di antara elemen anak, dalam kasus di mana 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 perluasan 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

Kami menyebutkan sebelumnya bahwa kontrol kustom apa pun yang memungkinkan pengguna untuk memfokuskannya harus memiliki indikator fokus visual. Biasanya indikator fokus itu sesingkat menggambar bentuk persegi panjang segera di sekitar persegi panjang pembatas normal kontrol. Persegi panjang untuk fokus visual adalah elemen serekan ke komposisi kontrol lainnya dalam templat kontrol, tetapi awalnya diatur dengan nilai VisibilitasDiciutkan karena kontrol belum difokuskan. Kemudian, 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 default akan menampilkan indikator fokus visual yang sesuai saat difokuskan (jika dapat difokuskan). Ada juga tampilan yang berpotensi berbeda tergantung pada tema yang dipilih pengguna (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 untuk mendapatkan indikator fokus visual pada kontrol yang berperilaku dan ditampilkan dengan benar. Tetapi jika Anda berniat untuk mengolah 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 dalam 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.

XAML

<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 tampak kosong. Cara kerja status visual adalah bahwa 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, ini berarti 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 dan Windows Phone keyboard

Perangkat Windows Phone biasanya tidak memiliki keyboard perangkat keras khusus. Namun, Panel Input Lunak (SIP) dapat mendukung beberapa skenario aksesibilitas keyboard. Pembaca layar dapat membaca input teks dari SIP Teks , termasuk mengumumkan penghapusan. Pengguna dapat menemukan di mana jari mereka berada karena pembaca layar dapat mendeteksi bahwa pengguna memindai kunci, dan membaca 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 merupakan prinsip aksesibilitas penting. Tombol panah seperti yang digunakan untuk menavigasi bagian-bagian dalam kontrol kompleks juga didukung melalui gerakan sentuh Narator. Setelah fokus mencapai kontrol yang bukan untuk input teks, Narator mendukung gerakan yang memanggil tindakan kontrol tersebut.

Pintasan keyboard biasanya tidak relevan untuk aplikasi Windows Phone, karena SIP tidak akan menyertakan tombol Kontrol atau Alt.

Contoh

Tip

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