Accessibility

Prof. Dr. Robin Nunkesser

Accessibility

Beispielprojekt

Vorgehen

Agent-generated example: csharp-maui-accessibility

  • Ziel: ein kleines, gut erklärbares Beispiel für Accessibility in MAUI
  • sichtbares Ergebnis: Label mit HeadingLevel, Bild mit Description, Button mit Hint, Switch mit gebundener Description
  • bewusst out of scope: Keyboards, Farbenblindheit, plattformspezifische Accessibility-APIs, WCAG

Verwendete Instructions

  • System- und Agent-Regeln: kleinster sinnvoller Scope, erst Kontext lesen, Änderungen verifizieren
  • .github/copilot-instructions.md: kleine, reviewbare Änderungen und echte Verifikation
  • .github/instructions/artifacts.instructions.md: kleine, explizite, verifizierbare Änderungen in artifacts/
  • .github/instructions/artifacts-consumers-education.instructions.md: didaktische Klarheit, ein Hauptkonzept, Foliensatzbezug und Vergleich mit dem manuellen Beispiel
  • .github/instructions/slides.instructions.md: knappe, gut scannbare Folien

Exakter Prompt

Erstelle ein kleines agent-generated example für Accessibility in einem Lehrprojekt dieses Repos.
Lies zuerst die relevanten Repository-Instructions und ermittle den zugehörigen Foliensatz.
Dokumentiere die verwendeten Instructions und den exakten Prompt, füge beides in den Foliensatz ein und vergleiche das Ergebnis mit dem bestehenden manuellen Beispiel.
Bevorzuge didaktische Klarheit, kleinen Scope und überprüfbare Ergebnisse.

Ergebnis

Lernziel

  • SemanticProperties.Description für Bilder und Steuerelemente setzen
  • SemanticProperties.HeadingLevel für Labels verwenden
  • SemanticProperties.Hint auf Buttons einsetzen
  • SemanticScreenReader.Announce() programmatisch auslösen

Die vier Kernkonzepte

  1. SemanticProperties.Description — beschreibt ein Element für Screen Reader
  2. SemanticProperties.HeadingLevel — strukturiert Inhalte als Überschriften
  3. SemanticProperties.Hint — gibt Benutzern einen Handlungshinweis
  4. SemanticScreenReader.Announce() — liest Text auf Ereignis laut vor

Bild: Description

<Image Source="dotnet_bot.png"
       HeightRequest="160"
       Aspect="AspectFit"
       SemanticProperties.Description="Der .NET Bot als Maskottchen" />
  • Description ersetzt den fehlenden alt-Text für Bilder.
  • Screen Reader liest diesen Text anstelle des Dateinamens vor.

Labels: HeadingLevel und Description

<Label Text="Barrierefreiheit in MAUI"
       Style="{StaticResource Headline}"
       SemanticProperties.HeadingLevel="Level1" />

<Label Text="Konzepte im Überblick"
       Style="{StaticResource SubHeadline}"
       SemanticProperties.HeadingLevel="Level2"
       SemanticProperties.Description="Konzepte im Ueberblick" />
  • HeadingLevel ermöglicht Navigation per Heading-Sprung im Screen Reader.
  • Description erlaubt eine Screen-Reader-optimierte Aussprache.

Button: Hint

<Button x:Name="GreetBtn"
        Text="Begrüßen"
        SemanticProperties.Hint="Liest eine Begrüßung laut vor"
        Clicked="OnGreetClicked"
        HorizontalOptions="Fill" />
  • Hint ergänzt den Buttontext um einen konkreten Handlungshinweis.
  • Screen Reader liest: “Begrüßen, Schaltfläche — Liest eine Begrüßung laut vor.”

Switch: gebundene Description

<Label x:Name="DarkModeLabel" Text="Dunkelmodus aktivieren:" />
<Switch SemanticProperties.Description=
    "{Binding Source={x:Reference DarkModeLabel}, Path=Text}" />
  • Der Switch hat keinen eigenen sichtbaren Text.
  • Das Binding übernimmt den Labeltext automatisch als Description.

SemanticScreenReader.Announce

private void OnGreetClicked(object sender, EventArgs e)
{
    var message = "Willkommen in der Accessibility-Demo!";
    GreetBtn.Text = message;
    SemanticScreenReader.Announce(message);
}
  • Löst eine Sprachausgabe unabhängig vom Fokus aus.
  • Nützlich nach Statuswechseln, Ladevorgängen oder Ergebnissen.

Vollständige Minimalversion von MainPage.xaml

<ScrollView>
  <VerticalStackLayout Padding="30" Spacing="20">
    <Label Text="Barrierefreiheit in MAUI"
           Style="{StaticResource Headline}"
           SemanticProperties.HeadingLevel="Level1" />
    <Label Text="Konzepte im Überblick"
           Style="{StaticResource SubHeadline}"
           SemanticProperties.HeadingLevel="Level2"
           SemanticProperties.Description="Konzepte im Ueberblick" />
    <Image Source="dotnet_bot.png" HeightRequest="160" Aspect="AspectFit"
           SemanticProperties.Description="Der .NET Bot als Maskottchen" />
    <Button x:Name="GreetBtn" Text="Begrüßen"
            SemanticProperties.Hint="Liest eine Begrüßung laut vor"
            Clicked="OnGreetClicked" HorizontalOptions="Fill" />
    <Label x:Name="DarkModeLabel" Text="Dunkelmodus aktivieren:" />
    <Switch SemanticProperties.Description=
        "{Binding Source={x:Reference DarkModeLabel}, Path=Text}" />
  </VerticalStackLayout>
</ScrollView>

Vollständige Minimalversion von MainPage.xaml.cs

namespace Accessibility;

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    private void OnGreetClicked(object sender, EventArgs e)
    {
        var message = "Willkommen in der Accessibility-Demo!";
        GreetBtn.Text = message;
        SemanticScreenReader.Announce(message);
    }
}

Typische Erweiterungen

  • IsInAccessibleTree="False" für rein dekorative Elemente setzen
  • AutomationId für UI-Tests vergeben
  • plattformspezifische Accessibility-Eigenschaften (z.B. iOS AccessibilityHint)
  • Tastaturnavigation und Kontrastanforderungen explizit testen

Vergleich

Agent-Beispiel vs. manuelles Beispiel

Kriterium Manuell Agent
Korrektheit
Konzeptabdeckung alle 4 Konzepte alle 4 Konzepte
Didaktische Klarheit gut besser fokussiert
Erklärbarkeit mit Zähler-Logik klare Announce-Semantik

Empfehlung

  • Beide Beispiele decken dieselben 4 Accessibility-Konzepte ab.
  • Agent-Version: kein Zähler-Overhead, Announce direkt sichtbar.
  • Manuelles Beispiel: bewährt, direkt in GitHub verfügbar.
  • Agent-Version als Ersatz empfohlen: gleiche Konzepte, fokussiertere Erklärbarkeit.