Benutzerdefinierte Automatisierungspeers

Benutzerdefinierte Automatisierungspeers

[ Dieser Artikel richtet sich an Windows 8.x- und Windows Phone 8.x-Entwickler, die Windows-Runtime-Apps schreiben. Wenn Sie für Windows 10 entwickeln, finden Sie weitere Informationen unter neueste Dokumentation]

Mit der Benutzeroberflächenautomatisierung wird ein Framework bereitgestellt, das Automatisierungsclients verwenden können, um die Benutzeroberflächen einer Vielzahl von UI-Plattformen und Frameworks zu untersuchen oder zu betreiben. Wenn Sie eine Windows Store-App mit C++, C# oder Visual Basic schreiben, wird die Benutzeroberflächenautomatisierung bereits von den Windows-Runtime-Klassen unterstützt, die Sie für Ihre UI verwenden. Sie können vorhandene nicht versiegelte Windows-Runtime-Klassen ableiten, um einen neuen UI-Steuerelementtyp oder eine Unterstützungsklasse zu definieren. Hierbei kann mit Ihrer Klasse möglicherweise Verhalten zur Unterstützung der Barrierefreiheit hinzugefügt werden, das die Standard-Benutzeroberflächenautomatisierung nicht bereitstellt. In diesem Fall sollten Sie die vorhandene Unterstützung der Benutzeroberflächenautomatisierung erweitern, indem Sie von der AutomationPeer-Klasse ableiten, die in der Basisimplementierung verwendet wird. Zudem sollten Sie Ihrer Peerimplementierung die notwendige Unterstützung hinzufügen und die Windows-Runtime-Steuerungsinfrastruktur anweisen, den neuen Peer zu erstellen.

Die Benutzeroberflächenautomatisierung ermöglicht nicht nur Anwendungen für die Barrierefreiheit und Hilfstechnologien wie Bildschirmleseprogramme, sondern auch Qualitätssicherungscode (Testcode). In beiden Szenarien können Benutzeroberflächenautomatisierungs-Clients die Benutzeroberflächenelemente untersuchen und die Benutzerinteraktion mit Ihrer App für Code simulieren, der nicht aus Ihrer App stammt. Informationen zur plattformübergreifenden Benutzeroberflächenautomatisierung und ihrer weiteren Bedeutung finden Sie unter Übersicht über die Benutzeroberflächenautomatisierung.

Es gibt zwei unterschiedliche Zielgruppen, von denen das Benutzeroberflächenautomatisierungs-Framework verwendet wird.

  • Von Clients für die Benutzeroberflächenautomatisierung werden Benutzeroberflächenautomatisierungs-APIs aufgerufen, um Informationen zur gesamten gegenwärtig für den Benutzer angezeigten Benutzeroberfläche abzurufen. Beispielsweise fungiert eine Hilfstechnologie wie etwa eine Bildschirmsprachausgabe als Benutzeroberflächenautomatisierungs-Client. Die Benutzeroberfläche wird als Struktur aus verwandten Automatisierungselementen dargestellt. Der Benutzeroberflächenautomatisierungs-Client benötigt u. U. Informationen zu jeweils nur einer App oder aber zur gesamten Struktur. Vom Benutzeroberflächenautomatisierungs-Client können Benutzeroberflächenautomatisierungs-APIs zum Navigieren in der Struktur und zum Lesen oder Ändern von Informationen in den Automatisierungselementen verwendet werden.
  • Von Anbietern für die Benutzeroberflächenautomatisierung werden Informationen zum Benutzeroberflächenautomatisierungs-Baum hinzugefügt. Dies erfolgt durch die Implementierung von APIs, von denen die Elemente in der Benutzeroberfläche verfügbar gemacht werden, die als Teil der App eingeführt wurde. Wenn Sie ein neues Steuerelement erstellen, sollten Sie jetzt als Teilnehmer des Benutzeroberflächenautomatisierungs-Anbieterszenarios fungieren. Als Anbieter sollten Sie aus Gründen der Barrierefreiheit und zu Testzwecken sicherstellen, dass alle Benutzeroberflächenautomatisierungs-Clients das Benutzeroberflächenautomatisierungs-Framework für die Interaktion mit Ihrem Steuerelement nutzen können.

Gewöhnlich sind im Benutzeroberflächenautomatisierungs-Framework parallele APIs vorhanden: eine API für Benutzeroberflächenautomatisierungs-Clients und eine andere API mit einem ähnlichen Namen für Benutzeroberflächenautomatisierungs-Anbieter. In diesem Thema geht es hauptsächlich um die APIs für den Benutzeroberflächenautomatisierungs-Anbieter und speziell um die Windows-Runtime-Klassen und -Schnittstellen, die eine Anbietererweiterbarkeit in diesem Benutzeroberflächenframework ermöglichen. Gelegentlich werden auch von Benutzeroberflächenautomatisierungs-Clients verwendete Benutzeroberflächenautomatisierungs-APIs angesprochen, um eine andere Perspektive zu bieten oder in einer Suchtabelle einen Vergleich von Client- und Anbieter-APIs zu veranschaulichen. Weitere Informationen zur Clientperspektive finden Sie im Programmierhandbuch für Benutzeroberflächenautomatisierungs-Clients.

Hinweis  

Benutzeroberflächenautomatisierungs-Clients verwenden normalerweise keinen verwalteten Code und werden meist auch nicht als Windows-Runtime-App implementiert (sondern als Desktop-Apps). Die Benutzeroberflächenautomatisierung basiert auf einem Standard, nicht auf einer bestimmten Implementierung oder einem bestimmten Framework. Viele vorhandene Benutzeroberflächenautomatisierungs-Clients, z. B. Hilfstechnologieprodukte wie Bildschirmleseprogramme, verwenden Component Object Model (COM)-Schnittstellen für die Interaktion mit der Benutzeroberflächenautomatisierung, dem System und den in untergeordneten Fenstern ausgeführten Apps. Weitere Informationen zu COM-Schnittstellen und zum Schreiben eines Benutzeroberflächenautomatisierungs-Clients mithilfe von COM finden Sie unter Grundlagen der Benutzeroberflächenautomatisierung.

 

Ermitteln des vorhandenen Zustands der Benutzeroberflächenautomatisierung für benutzerdefinierte UI-Klassen

Bevor Sie versuchen, einen Automatisierungspeer für ein benutzerdefiniertes Steuerelement zu implementieren, sollten Sie testen, ob die Basisklasse und der Automatisierungspeer bereits die erforderliche Barrierefreiheit oder Automatisierungsunterstützung bereitstellen. In vielen Fällen kann die Kombination aus FrameworkElementAutomationPeer-Implementierungen, bestimmten Peers und den Mustern, die sie implementieren, eine einfache Barrierefreiheit bieten, die den Anforderungen genügt. Dies hängt davon ab, wie viele Änderungen Sie an der Objektmodellverfügbarkeit Ihres Steuerelements im Vergleich zur Basisklasse vorgenommen haben. Zudem hängt dies davon ab, ob Ihre Ergänzungen der Basisklassenfunktionalität mit den neuen UI-Elementen im Vorlagenvertrag oder mit der visuellen Darstellung des Steuerelements korrelieren. In einigen Fällen führen Ihre Änderungen möglicherweise zu neuen Aspekten der Benutzererfahrung, die eine zusätzliche Unterstützung der Barrierefreiheit erfordern.

Auch wenn durch die Verwendung der vorhandenen Basispeerklasse eine grundlegende Unterstützung für die Barrierefreiheit geboten wird, empfiehlt es sich, einen Peer zu definieren. So können Sie die Benutzeroberflächenautomatisierung mit genauen ClassName-Informationen für automatisierte Testszenarien versorgen. Diese Überlegung ist besonders wichtig, wenn Sie ein Steuerelement für den Einsatz in Drittanbieterlösungen entwerfen.

Automatisierungspeerklassen

Die Windows-Runtime baut auf vorhandenen Techniken und Konventionen für die Benutzeroberflächenautomatisierung auf, die von vorherigen Benutzeroberflächenframeworks mit verwaltetem Code verwendet wurden, z. B. Windows Forms, Windows Presentation Foundation (WPF) und Microsoft Silverlight. Viele der Steuerelementklassen und deren Funktion und Zweck entstammen auch einem vorherigen Benutzeroberflächenframework.

Üblicherweise beginnen Peerklassennamen mit dem Namen der Steuerelementklasse und enden mit "AutomationPeer". ButtonAutomationPeer ist beispielsweise die Peerklasse für die Button-Steuerelementklasse.

Hinweis  Im Rahmen dieses Themas räumen wir den Eigenschaften, die sich auf die Barrierefreiheit beziehen, beim Implementieren eines Peers für ein Steuerelement eine höhere Priorität ein. In einem allgemeineren Konzept für die Unterstützung der Benutzeroberflächenautomatisierung sollten Sie jedoch einen Peer gemäß den Empfehlungen im Programmierhandbuch für Benutzeroberflächenautomatisierungs-Anbieter und in den Grundlagen der Benutzeroberflächenautomatisierung implementieren. In diesen Themen werden zwar keine spezifischen AutomationPeer-APIs behandelt, die Sie zum Bereitstellen der Informationen im Windows-Runtime-Framework für die Benutzeroberflächenautomatisierung verwenden können, aber es werden die Eigenschaften beschrieben, mit denen Ihre Klasse identifiziert wird oder andere Informationen oder Interaktionen bereitgestellt werden.
 

Peers, Muster und Steuerelementtypen

Ein Steuerelementmuster ist eine Schnittstellenimplementierung, die einen bestimmten Aspekt der Funktionalität eines Steuerelements für einen Benutzeroberflächenautomatisierungs-Client verfügbar macht. Benutzeroberflächenautomatisierungs-Clients verwenden die Eigenschaften und Methoden, die über ein Steuerelementmuster verfügbar gemacht werden, um Informationen über die Funktionen des Steuerelements abzurufen oder das Verhalten des Steuerelements zur Laufzeit zu ändern.

Steuerelementmuster ermöglichen es, die Funktionen eines Steuerelements unabhängig vom Typ oder vom Aussehen des Steuerelements zu kategorisieren und verfügbar zu machen. Ein Steuerelement, das eine tabellarische Oberfläche darstellt, verwendet das Grid-Steuerelementmuster, um die Anzahl der Zeilen und Spalten in der Tabelle verfügbar zu machen und einem Benutzeroberflächenautomatisierungs-Client zu ermöglichen, Objekte aus der Tabelle abzurufen. Der Benutzeroberflächenautomatisierungs-Client kann das Invoke Steuerelementmuster für aufrufbare Steuerelemente (z. B. Schaltflächen) und das Scroll-Steuerelementmuster für Steuerelemente mit Bildlaufleisten (z. B. Listenfelder, Listenansichten oder Kombinationsfelder) verwenden. Jedes Steuerelementmuster stellt eine separate Funktion dar, und Steuerelementmuster können kombiniert werden, um den gesamten Funktionsumfang zu beschreiben, der von einem bestimmten Steuerelement unterstützt wird.

Steuerelementmuster verhalten sich zur Benutzeroberfläche wie Schnittstellen zu COM-Objekten. In COM können Sie von einem Objekt abfragen, welche Schnittstellen es unterstützt, und dann mithilfe dieser Schnittstellen auf die Funktionen zugreifen. Bei der Benutzeroberflächenautomatisierung können Benutzeroberflächenautomatisierungs-Clients von einem Benutzeroberflächenautomatisierungs-Element abfragen, welche Steuerelementmuster es unterstützt, und dann über die vom unterstützten Steuerelementmuster verfügbar gemachten Eigenschaften, Methoden, Ereignisse und Strukturen mit dem Element und dem Peersteuerelement interagieren.

Eine der Hauptaufgaben eines Automatisierungspeers besteht darin, dem Benutzeroberflächenautomatisierungs-Client zu melden, welche Steuerelementmuster das UI-Element über seinen Peer unterstützen kann. Dazu werden von Benutzeroberflächenautomatisierungs-Anbietern neue Peers implementiert, mit denen das Verhalten der GetPattern-Methode durch Außerkraftsetzung der GetPatternCore-Methode geändert wird. Benutzeroberflächenautomatisierungs-Clients führen Aufrufe durch, die vom Benutzeroberflächenautomatisierungs-Anbieter dem aufrufenden GetPattern-Element zugeordnet werden. Benutzeroberflächenautomatisierungs-Clients fragen jedes spezielle Muster ab, mit dem sie interagieren möchten. Wenn der Peer das Muster unterstützt, gibt er einen Objektverweis auf sich selbst oder andernfalls null zurück. Wird nicht null zurückgegeben, erwartet der Benutzeroberflächenautomatisierungs-Client, dass er APIs der Musterschnittstelle als Client aufrufen kann, um mit diesem Steuerelementmuster zu interagieren.

Ein Steuerelementtyp ist eine Möglichkeit, die Funktionalität eines vom Peer dargestellten Steuerelements allgemein zu definieren. Dieses Konzept unterscheidet sich insofern von dem eines Steuerelementmusters, da ein Muster die Benutzeroberflächenautomatisierung informiert, welche Informationen sie abrufen kann oder welche Aktionen sie über eine bestimmte Schnittstelle ausführen kann, während sich der Steuerelementtyp eine Ebene höher befindet. Jeder Steuerelementtyp verfügt über Informationen zu den folgenden Aspekten der Benutzeroberflächenautomatisierung:

  • Steuerelementmuster für die Benutzeroberflächenautomatisierung: Ein Steuerelementtyp kann mehrere Muster unterstützen, die jeweils eine andere Klassifizierung von Informationen oder Interaktionen darstellen. Jeder Steuerelementtyp verfügt über einen Satz von Steuerelementmustern, die das Steuerelement unterstützen muss. Dabei ist ein Satz optional, und der andere darf vom Steuerelement nicht unterstützt werden.
  • Eigenschaftswerte für die Benutzeroberflächenautomatisierung: Jeder Steuerelementtyp hat einen Satz von Eigenschaften, die das Steuerelement unterstützen muss. Dabei handelt es sich um die allgemeinen Eigenschaften, die unter Übersicht über Eigenschaften für die Benutzeroberflächenautomatisierung beschrieben werden, nicht um die musterspezifischen Eigenschaften.
  • Ereignisse für die Benutzeroberflächenautomatisierung: Jeder Steuerelementtyp hat einen Satz von Ereignissen, die das Steuerelement unterstützen muss. Auch hier handelt es sich nicht um musterspezifische Ereignisse, sondern um die unter Übersicht über Ereignisse für die Benutzeroberflächenautomatisierung beschriebenen Ereignisse.
  • Baumstruktur der Benutzeroberflächenautomatisierung: Jeder Steuerelementtyp definiert, wie das Steuerelement in der Baumstruktur der Benutzeroberflächenautomatisierung dargestellt werden muss.

Unabhängig von der Implementierungsweise von Automatisierungspeers für das Framework sind die Funktionen von Benutzeroberflächenautomatisierungs-Clients nicht an die Windows-Runtime gebunden. Es ist sogar wahrscheinlich, dass vorhandene Benutzeroberflächenautomatisierungs-Clients wie beispielsweise Hilfstechnologien andere Programmiermodelle (z. B. COM) verwenden. In COM können Clients QueryInterface für die Schnittstelle des COM-Steuerelementmusters, das das angeforderte Muster implementiert, oder das allgemeine Benutzeroberflächenautomatisierungs-Framework für Eigenschaften, Ereignisse oder die Strukturuntersuchung verwenden. Mithilfe des Benutzeroberflächenautomatisierungs-Frameworks wird für die Muster das Marshalling in Windows-Runtime-Code vorgenommen, der für den Benutzeroberflächenautomatisierungs-Anbieter der App und den entsprechenden Peer ausgeführt wird.

Wenn Sie Steuerelementmuster für ein Framework mit verwaltetem Code implementieren, z. B. eine Windows Store-App mit C# oder Microsoft Visual Basic, können Sie für die Darstellung dieser Muster .NET Framework-Schnittstellen anstelle von COM-Schnittstellen verwenden. Die Benutzeroberflächenautomatisierungs-Musterschnittstelle für eine Microsoft .NET-Anbieterimplementierung des Invoke-Musters ist beispielsweise IInvokeProvider.

Eine Liste mit Steuerelementmustern, Anbieterschnittstellen und deren Zweck finden Sie unter Steuerelementmuster und -schnittstellen. Eine Liste der Steuerelementtypen finden Sie unter Übersicht über Steuerelementtypen für die Benutzeroberflächenautomatisierung.

Leitfaden für die Implementierung von Steuerelementmustern

Die Steuerelementmuster und ihr jeweiliger Zweck sind Bestandteil einer umfangreicheren Definition des Benutzeroberflächenautomatisierungs-Frameworks und gelten nicht nur für die Unterstützung der Barrierefreiheit in einer Windows Store-App. Stellen Sie beim Implementieren eines Steuerelementmusters sicher, dass die Implementierung den auf MSDN und in der Spezifikation für die Benutzeroberflächenautomatisierung dokumentierten Richtlinien entspricht. Wenn Sie Unterstützung benötigen, können Sie im Allgemeinen die MSDN-Themen verwenden und müssen nicht die Spezifikation zurate ziehen. Einen Leitfaden für die einzelnen Muster finden Sie unter Implementieren von Steuerelementmustern für die Benutzeroberflächenautomatisierung. Jedes Thema in diesem Bereich enthält einen Abschnitt mit Implementierungsrichtlinien und -konventionen und einen mit den erforderlichen Membern. Die Richtlinien beziehen sich in der Regel auf bestimmte APIs der relevanten Steuerelementmuster-Schnittstelle in der Referenz Steuerelementmuster-Schnittstellen für Anbieter. Bei diesen Schnittstellen handelt es sich um die systemeigenen Schnittstellen bzw. COM-Schnittstellen (und die zugehörigen APIs verwenden eine Syntax im COM-Stil). Für alles, was Sie hier sehen, gibt es jedoch eine Entsprechung im Windows.UI.Xaml.Automation.Provider-Namespace.

Wenn Sie die Standardautomatisierungspeers verwenden und ihr Verhalten erweitern, ist zu beachten, dass diese Peers bereits gemäß den Richtlinien für die Benutzeroberflächenautomatisierung für Anbieter geschrieben wurden. Wenn sie Steuerelementmuster unterstützen, können Sie sich darauf verlassen, dass die jeweiligen Muster den Richtlinien unter Implementieren von Steuerelementmustern für die Benutzeroberflächenautomatisierung entsprechen. Wenn ein Steuerelementpeer meldet, dass er einen durch die Benutzeroberflächenautomatisierung definierten Steuerelementtyp darstellt, orientiert sich dieser Peer an den unter Unterstützen von Steuerelementtypen für die Benutzeroberflächenautomatisierung dokumentierten Richtlinien.

Trotzdem benötigen Sie u. U. weitere Richtlinien für Steuerelementmuster oder -typen, um in Ihrer Peerimplementierung den Empfehlungen für die Benutzeroberflächenautomatisierung zu folgen. Dies ist besonders dann der Fall, wenn Sie eine Unterstützung für Muster oder Steuerelementtypen implementieren, die noch nicht als Standardimplementierung in einem Windows-Runtime-Steuerelement vorhanden ist. Das Muster für Anmerkungen ist z. B. in keinem der standardmäßigen XAML-Steuerelemente implementiert. Vielleicht haben Sie aber eine App, die Anmerkungen intensiv nutzt, und möchten daher den Zugriff auf diese Funktionalität ermöglichen. Für dieses Szenario sollte Ihr Peer IAnnotationProvider implementieren und sich vermutlich als Document-Steuerelementtyp mit entsprechenden Eigenschaften melden. Dies ist ein Hinweis darauf, dass Ihre Dokumente Anmerkungen unterstützen.

Wir empfehlen, die Ratschläge für die Muster unter Implementieren von Steuerelementmustern für die Benutzeroberflächenautomatisierung oder für Steuerelementtypen unter Unterstützen von Steuerelementtypen für die Benutzeroberflächenautomatisierung zur Orientierung und als allgemeinen Leitfaden zu nutzen. Sie können auch einigen der API-Links folgen, unter denen Sie Beschreibungen und Anmerkungen zum Zweck der APIs finden. Einzelheiten zur speziellen Syntax für die Programmierung von Windows Store-Apps finden Sie unter der entsprechenden API im Windows.UI.Xaml.Automation.Provider-Namespace und den zugehörigen Referenzseiten.

Auf MSDN finden Sie außerdem eine Dokumentation für die verwaltete Benutzeroberflächenautomatisierung (System.Windows.Automation und verwandte Informationen). Diese Dokumentation war ursprünglich für WPF oder .NET-Version 4 gedacht und wurde seitdem nicht aktualisiert. Beispielsweise gibt es keine API und keine Dokumentation für Steuerelementtypen und -muster für die Benutzeroberflächenautomatisierung, die ab Windows 7 hinzugefügt wurden. Wir empfehlen, diese Dokumentation oder die System.Windows.Automation-APIs nicht zu verwenden. Nutzen Sie stattdessen die Konzepte und Empfehlungen in der aktuellen Dokumentation für die Benutzeroberflächenautomatisierung, die sich an der Windows-Programmierung (und COM) orientiert. Verwenden Sie dann die APIs in Windows.UI.Xaml.Automation und verwandten Namespaces, um die Peers zu implementieren, indem Sie die Windows-Runtime-API-Entsprechungen der in der konzeptionellen Dokumentation genannten COM-API-Namen extrapolieren.

Integrierte Automatisierungspeerklassen

Im Allgemeinen implementieren Elemente eine Automatisierungspeerklasse, wenn sie UI-Aktivität vom Benutzer akzeptieren. Ein weiterer Fall ist das Vorhandensein von Informationen, die Benutzer von Hilfstechnologien benötigen, mit denen die interaktive oder aussagekräftige Benutzeroberfläche von Apps dargestellt wird. Nicht alle visuellen Windows-Runtime-Elemente verfügen über Automatisierungspeers. Beispiele für Klassen, die Automatisierungspeers implementieren, sind Button und TextBox. Beispiele für Klassen, die keine Automatisierungspeers implementieren, sind Border und Klassen auf Basis von Panel, z. B. Grid und Canvas. Ein Panel weist keinen Peer auf, weil es nur ein visuelles Layoutverhalten bereitstellt. Benutzer haben keine für die Barrierefreiheit relevante Möglichkeit, mit einem Panel zu interagieren. Unabhängig davon, welche untergeordneten Elemente ein Panel enthält, werden diese den Benutzeroberflächenautomatisierungs-Bäumen als untergeordnete Elemente des nächsten verfügbaren übergeordneten Elements in der Struktur gemeldet, das über eine Peer- oder Elementdarstellung verfügt.

Prozessgrenzen der Benutzeroberflächenautomatisierung und der Windows-Runtime

In der Regel wird Benutzeroberflächenautomatisierungs-Client-Code, der auf eine Windows-Runtime-App zugreift, außerhalb des Prozesses ausgeführt. Die Infrastruktur des Benutzeroberflächenautomatisierungs-Frameworks ermöglicht es, Informationen über Prozessgrenzen hinweg zu übertragen. Weitere Informationen zu diesem Konzept finden Sie in den Grundlagen der Benutzeroberflächenautomatisierung.

OnCreateAutomationPeer

Alle Klassen, die von UIElement abgeleitet werden, enthalten die geschützte virtuelle Methode OnCreateAutomationPeer. Die Windows-Runtime-Objektinitialisierungssequenz für Automatisierungspeers ruft OnCreateAutomationPeer auf, um das Automatisierungspeerobjekt für jedes Steuerelement abzurufen und so einen Benutzeroberflächenautomatisierungs-Baum zur Laufzeitverwendung zu erstellen. Der Benutzeroberflächenautomatisierungs-Code kann den Peer verwenden, um Informationen über die Merkmale und Features eines Steuerelements abzurufen und mithilfe der Steuerelementmuster die interaktive Verwendung des Steuerelements zu simulieren. Ein benutzerdefiniertes Steuerelement, das Automatisierung unterstützt, muss OnCreateAutomationPeer außer Kraft setzen und eine Instanz der Klasse zurückgeben, die von AutomationPeer abgeleitet wird. Wenn beispielsweise ein benutzerdefiniertes Steuerelement von der Klasse ButtonBase abgeleitet wird, sollte das von OnCreateAutomationPeer zurückgegebene Objekt von ButtonBaseAutomationPeer abgeleitet werden.

Wenn Sie eine benutzerdefinierte Steuerelementklasse schreiben und außerdem einen neuen Automatisierungspeer bereitstellen möchten, sollten Sie die OnCreateAutomationPeer-Methode für das benutzerdefinierte Steuerelement außer Kraft setzen, sodass eine neue Instanz Ihres Peers zurückgegeben wird. Die Peerklasse muss direkt oder indirekt von AutomationPeer abgeleitet werden.

Mit dem folgenden Code wird beispielsweise deklariert, dass das benutzerdefinierte NumericUpDown-Steuerelement den Peer NumericUpDownPeer zur Benutzeroberflächenautomatisierung verwenden soll.


using Windows.UI.Xaml.Automation.Peers;
...
public class NumericUpDown : RangeBase {
    public NumericUpDown() {
    // other initialization; DefaultStyleKey etc.
    }
    ...
    protected override AutomationPeer OnCreateAutomationPeer()
    {
        return new NumericUpDownAutomationPeer(this);
    }
}

Hinweis  Es wird empfohlen, dass die OnCreateAutomationPeer-Implementierung lediglich eine neue Instanz des benutzerdefinierten Automatisierungspeers initialisiert, das aufrufende Steuerelement als Besitzer übergibt und diese Instanz zurückgibt. Versuchen Sie nicht, in diese Methode zusätzliche Logik einzubinden. Besonders Logik, die möglicherweise zur Zerstörung des AutomationPeer-Elements innerhalb desselben Aufrufs führt, kann ein unvorhergesehenes Laufzeitverhalten zur Folge haben.
 

In typischen Implementierungen von OnCreateAutomationPeer ist owner als this/Me angegeben, da die Außerkraftsetzung der Methode im gleichen Umfang stattfindet wie der Rest der Steuerelement-Klassendefinition.

Die tatsächliche Peerklassendefinition kann in derselben Codedatei wie das Steuerelement oder in einer separaten Codedatei erfolgen. Die Windows-Runtime-Peerdefinitionen befinden sich alle im Windows.UI.Xaml.Automation.Peers-Namespace, also getrennt von den Steuerelementen, für die sie Peers bereitstellen. Sie können Ihre Peers auch in separaten Namespaces deklarieren, sofern Sie auf die erforderlichen Namespaces für den OnCreateAutomationPeer-Methodenaufruf verweisen.

Auswählen der richtigen Peerbasisklasse

Stellen Sie sicher, dass Ihr AutomationPeer von einer Basisklasse abgeleitet wird, die am besten mit der vorhandenen Peerlogik der Steuerelementklasse übereinstimmt, von der Sie ableiten. Im vorherigen Beispiel ist eine RangeBaseAutomationPeer-Klasse verfügbar, auf der Ihr Peer basieren sollte, da NumericUpDown von RangeBase abgeleitet wird. Indem Sie parallel zu der Art, wie Sie das Steuerelement selbst ableiten, die am besten passende Peerklasse verwenden, können Sie verhindern, dass zumindest ein Teil der IRangeValueProvider-Funktionalität außer Kraft gesetzt wird, da diese bereits von der Basispeerklasse implementiert wird.

Die Control-Basisklasse besitzt keine entsprechende Peerklasse. Wenn Sie eine Peerklasse benötigen, die mit einem benutzerdefinierten Steuerelement übereinstimmt, das von Control abgeleitet wird, leiten Sie die benutzerdefinierte Peerklasse von FrameworkElementAutomationPeer ab.

Wenn Sie direkt von ContentControl ableiten, hat diese Klasse kein standardmäßiges Automatisierungspeerverhalten, da keine OnCreateAutomationPeer-Implementierung vorhanden ist, die auf eine Peerklasse verweist. Implementieren Sie also entweder OnCreateAutomationPeer, um Ihren eigenen Peer zu verwenden, oder verwenden Sie FrameworkElementAutomationPeer als Peer, wenn die hiermit bereitgestellte Unterstützung für die Barrierefreiheit für Ihr Steuerelement ausreichend ist.

Hinweis  Normalerweise führen Sie keine Ableitungen von AutomationPeer anstelle von FrameworkElementAutomationPeer durch. Beim direkten Ableiten von AutomationPeer müssen Sie einen Großteil der grundlegenden Unterstützung der Barrierefreiheit duplizieren, die sonst über FrameworkElementAutomationPeer bereitgestellt wird.
 

Initialisierung einer benutzerdefinierten Peerklasse

Der Automatisierungspeer sollte einen typsicheren Konstruktor definieren, der eine Instanz des Besitzersteuerelements für die Basisinitialisierung verwendet. Im nächsten Beispiel übergibt die Implementierung den owner-Wert an die RangeBaseAutomationPeer-Basis (und letztendlich verwendet FrameworkElementAutomationPeer dann tatsächlich owner, um FrameworkElementAutomationPeer.Owner festzulegen).


public NumericUpDownAutomationPeer(NumericUpDown owner): base(owner)
{}

Hauptmethoden von "AutomationPeer"

Aufgrund der Windows-Runtime-Infrastruktur sind die Methoden eines Automatisierungspeers, die außer Kraft gesetzt werden können, Teil eines Methodenpaars: der öffentlichen Zugriffsmethode, die der Benutzeroberflächenautomatisierungs-Anbieter als Weiterleitungspunkt für Benutzeroberflächenautomatisierungs-Clients verwendet, und der geschützten "Core"-Anpassungsmethode, die von einer Windows Runtime-Klasse außer Kraft gesetzt werden kann, um das Verhalten zu beeinflussen. Das Methodenpaar wird standardmäßig so gebündelt, dass mit dem Aufruf der Zugriffsmethode immer die parallele "Core"-Methode aufgerufen wird, die die Anbieterimplementierung besitzt oder als Fallback die Standardimplementierung aus der Windows-Runtime aufruft.

Setzen Sie beim Implementieren eines Peers für ein benutzerdefiniertes Steuerelement eine beliebige "Core"-Methode aus der Basis-Automatisierungspeerklasse außer Kraft, in der Sie für Ihr benutzerdefiniertes Steuerelement spezifisches Verhalten verfügbar machen möchten. Der Benutzeroberflächenautomatisierungs-Code ruft durch Aufruf der öffentlichen Methoden der Peerklasse Informationen über Ihr Steuerelement ab. Um Informationen zu Ihrem Steuerelement zu bieten, setzen Sie jede Methode mit einem Namen außer Kraft, der auf "Core" endet, wenn durch die Implementierung und das Design Ihres Steuerelements Barrierefreiheitsszenarien oder andere Benutzeroberflächenautomatisierungs-Szenarien erstellt werden, die von jenen abweichen, die von der Basis-Automatisierungspeerklasse unterstützt werden.

Zumindest sollten Sie jedes Mal, wenn Sie eine neue Peerklasse definieren, die Methode GetClassNameCore implementieren, so wie im nächsten Beispiel gezeigt.


protected override string GetClassNameCore()
{
    return "NumericUpDown";
}

Hinweis  Es ist ratsam, die Zeichenfolgen als Konstanten zu speichern, anstatt direkt in der Methode. Die Entscheidung liegt jedoch bei Ihnen. Für GetClassNameCore müssen Sie diese Zeichenfolge nicht lokalisieren. Die LocalizedControlType-Eigenschaft wird jeweils verwendet, wenn ein Benutzeroberflächenautomatisierungs-Client eine lokalisierte Zeichenfolge benötigt (nicht ClassName).
 

GetAutomationControlType

Beim Melden der Merkmale der Objekte in einem Benutzeroberflächenautomatisierungs-Baum verwenden einige Hilfstechnologien den Wert GetAutomationControlType direkt – als zusätzliche Information über das Name-Element der Benutzeroberflächenautomatisierung hinaus. Wenn sich Ihr Steuerelement erheblich von dem Steuerelement unterscheidet, von dem Sie ableiten, und Sie einen anderen Steuerelementtyp melden möchten als den, der durch die vom Steuerelement verwendete Basispeerklasse gemeldet wird, müssen Sie einen Peer implementieren und in Ihrer Implementierung des Peers GetAutomationControlTypeCore außer Kraft setzen. Dies ist besonders wichtig, wenn Sie von einer allgemeinen Basisklasse wie ItemsControl oder ContentControl ableiten, in der der Peer keine genauen Informationen über den Steuerelementtyp liefert.

Ihre Implementierung von GetAutomationControlTypeCore beschreibt Ihr Steuerelement, indem ein AutomationControlType-Wert zurückgegeben wird. Obwohl Sie AutomationControlType.Custom zurückgeben können, sollten Sie einen der spezifischeren Steuerelementtypen zurückgegeben, falls dieser die Hauptszenarien Ihres Steuerelements genauer beschreibt. Hier sehen Sie ein Beispiel.



protected override AutomationControlType GetAutomationControlTypeCore()
{
    return AutomationControlType.Spinner;
}

Hinweis  Nur wenn Sie AutomationControlType.Custom angeben, müssen Sie GetLocalizedControlTypeCore implementieren, um für Clients einen LocalizedControlType-Eigenschaftswert bereitzustellen. Die allgemeine Benutzeroberflächenautomatisierungs-Infrastruktur bietet übersetzte Zeichenfolgen für jeden möglichen AutomationControlType-Wert, mit Ausnahme von AutomationControlType.Custom.
 

"GetPattern" und "GetPatternCore"

Die Peerimplementierung von GetPatternCore gibt das Objekt zurück, von dem das im Eingabeparameter angeforderte Muster unterstützt wird. Dabei ruft ein Benutzeroberflächenautomatisierungs-Client eine Methode auf, die an die GetPattern-Methode des Anbieters weitergeleitet wird, und gibt einen PatternInterface-Enumerationswert an, mit dem das angeforderte Muster benannt wird. Ihre Außerkraftsetzung von GetPatternCore sollte das Objekt zurückgeben, mit dem das angegebene Muster implementiert wird. Bei diesem Objekt handelt es sich um den Peer selbst, da von diesem bei jeder Meldung, dass er ein Muster unterstützt, die entsprechende Musterschnittstelle implementiert werden sollte. Wenn Ihr Peer über keine benutzerdefinierte Implementierung eines Musters verfügt, Sie jedoch wissen, dass das Muster von der Basis des Peers implementiert wird, können Sie die Implementierung des Basistyps von GetPatternCore über das GetPatternCore-Element aufrufen. Vom GetPatternCore-Element eines Peers sollte null zurückgegeben werden, wenn ein Muster vom Peer nicht unterstützt wird. Anstatt jedoch null direkt von Ihrer Implementierung zurückzugeben, würden Sie gewöhnlich den Aufruf an die Basisimplementierung dafür nutzen, für jedes nicht unterstützte Muster null zurückzugeben.

Wird ein Muster unterstützt, kann die GetPatternCore-Implementierung this oder Me zurückgegeben. Es wird erwartet, dass der Benutzeroberflächenautomatisierungs-Clients den GetPattern-Rückgabewert in die angeforderte Musterschnittstelle umwandelt, sofern dieser nicht null ist.

Wenn eine Peerklasse von einem anderen Peer erbt und die notwendige Unterstützung und das Melden des Musters bereits von der Basisklasse behandelt wird, ist die Implementierung von GetPatternCore nicht notwendig. Wenn Sie beispielsweise ein Bereichssteuerelement implementieren, das von RangeBase abgeleitet wird, und Ihr Peer von RangeBaseAutomationPeer abgeleitet wird, gibt dieser Peer sich selbst für PatternInterface.RangeValue zurück und besitzt funktionierende Implementierungen der IRangeValueProvider-Schnittstelle, die das Muster unterstützt.

Obwohl dies nicht der buchstäbliche Code ist, kommt dieses Beispiel der Implementierung von GetPatternCore sehr nahe, die bereits in RangeBaseAutomationPeer vorhanden ist.


protected override object GetPatternCore(PatternInterface patternInterface)
{
    if (patternInterface == PatternInterface.RangeValue)
    {
        return this;
    }
    return base.GetPattern(patternInterface);
}

Wenn Sie einen Peer implementieren, der nicht all die Unterstützung bietet, die Sie von einer Basispeerklasse benötigen, oder wenn Sie die Gruppe der Muster, die von der Basis geerbt und von Ihrem Peer unterstützt werden, ändern oder hinzufügen möchten, sollten Sie GetPatternCore überschreiben, damit Benutzeroberflächenautomatisierungs-Clients die Muster verwenden können.

Unter Windows.UI.Xaml.Automation.Provider finden Sie eine Liste der Anbietermuster, die in der Windows-Runtime-Implementierung der Benutzeroberflächenautomatisierungs-Unterstützung verfügbar sind. Jedes solche Muster hat einen entsprechenden Wert der PatternInterface-Enumeration. Dies ist die Art, in der Benutzeroberflächenautomatisierungs-Clients das Muster in einem GetPattern-Aufruf anfordern.

Ein Peer kann melden, dass er mehrere Muster unterstützt. In diesem Fall sollte die Außerkraftsetzung eine Rückgabepfadlogik für jeden unterstützten PatternInterface-Wert enthalten und den Peer bei jeder Übereinstimmung zurückgeben. Es wird erwartet, dass der Aufrufer nur jeweils eine Schnittstelle anfordert und dass der Aufrufer entscheiden kann, eine Umwandlung für die erwartete Schnittstelle durchzuführen.

Hier sehen Sie ein Beispiel für eine GetPatternCore-Außerkraftsetzung für einen benutzerdefinierten Peer. Der Peer meldet, dass die beiden Muster IRangeValueProvider und IToggleProvider unterstützt werden. Bei dem hier verwendeten Steuerelement handelt es sich um ein Steuerelement zum Anzeigen von Medien, das als Vollbild (Umschaltmodus) dargestellt werden kann und über eine Fortschrittsleiste verfügt, auf der Benutzer eine Position (das Bereichssteuerelement) auswählen können. Dieser Code stammt aus dem XAML-Beispiel für Barrierefreiheit.


protected override object GetPatternCore(PatternInterface patternInterface)
{
    if (patternInterface == PatternInterface.RangeValue)
    {
        return this;
    }
    else if (patternInterface == PatternInterface.Toggle)
    {
        return this;
    }
    return null;
}

Weiterleiten von Mustern aus Unterelementen

Eine GetPatternCore-Methodenimplementierung kann auch ein Unterelement oder einen Teil als Musteranbieter für den Host angeben. Dieses Beispiel veranschaulicht, wie mit ItemsControl die Behandlung des Bildlaufmusters an den Peer des internen ScrollViewer-Steuerelements übergeben wird. Um ein Unterelement für die Musterbehandlung anzugeben, ruft dieser Code das Unterelementobjekt ab, erstellt mit der FrameworkElement.CreatePeerForElement-Methode einen Peer für das Unterelement und gibt den neuen Peer zurück.


protected override object GetPatternCore(PatternInterface patternInterface)
{
    if (patternInterface == PatternInterface.Scroll)
    {
        ItemsControl owner = (ItemsControl) base.Owner;
        UIElement itemsHost = owner.ItemsHost;
        ScrollViewer element = null;
        while (itemsHost != owner)
        {
            itemsHost = VisualTreeHelper.GetParent(itemsHost) as UIElement;
            element = itemsHost as ScrollViewer;
            if (element != null)
            {
                break;
            }
        }
        if (element != null)
        {
            AutomationPeer peer = FrameworkElementAutomationPeer.CreatePeerForElement(element);
            if ((peer != null) && (peer is IScrollProvider))
            {
                return (IScrollProvider) peer;
            }
        }
    }
    return base.GetPatternCore(patternInterface);
}

Andere Core-Methoden

Ihr Steuerelement muss vielleicht Tastaturentsprechungen für primäre Szenarien unterstützen. Weitere Informationen darüber, warum dies erforderlich sein kann, finden Sie unter Implementieren von Barrierefreiheit für den Tastaturzugriff. Die Implementierung der Schlüsselunterstützung ist zwingend Teil des Codes für das Steuerelement und nicht des Codes für den Peer, da es sich hierbei um einen Teil der Logik eines Steuerelements handelt. Ihre Peerklasse sollte die GetAcceleratorKeyCore- und GetAccessKeyCore-Methoden außer Kraft setzen, um den Benutzeroberflächenautomatisierungs-Clients zu melden, welche Schlüssel verwendet werden. Bedenken Sie, dass Zeichenfolgen, in denen Schlüsselinformationen gemeldet werden, eventuell lokalisiert werden müssen und daher aus Ressourcen stammen sollten, nicht aus hartcodierten Zeichenfolgen.

Wenn Sie einen Peer für eine Klasse bereitstellen, die eine Auflistung unterstützt, sollte am besten sowohl von Funktionsklassen als auch von Peerklassen abgeleitet werden, die bereits diese Art von Auflistungsunterstützung besitzen. Wenn dies nicht möglich ist, müssen Peers für Steuerelemente, die untergeordnete Auflistungen verwalten, vielleicht die auflistungsbezogene Peermethode GetChildrenCore überschreiben, um dem Benutzeroberflächenautomatisierungs-Baum die Beziehungen zwischen übergeordneten und untergeordneten Elementen korrekt zu melden.

Spielen Sie die Methoden IsContentElementCore und IsControlElementCore ein, um anzugeben, ob Ihr Steuerelement Dateninhalt enthält und/oder eine interaktive Rolle auf der Benutzeroberfläche ausübt. Standardmäßig geben beide Methoden true zurück. Diese Einstellungen verbessern die Benutzerfreundlichkeit von Hilfstechnologien wie Bildschirmleseprogrammen, die diese Methoden ggf. zum Filtern der Automatisierungsstruktur verwenden. Wenn Ihre GetPatternCore-Methode die Musterbehandlung an einen Unterelementpeer überträgt, kann die IsControlElementCore-Methode des Unterelementpeers false zurückgeben, um den Unterelementpeer in der Automatisierungsstruktur auszublenden.

Einige Steuerelemente bieten u. U. Unterstützung für Bezeichnungsszenarien, in denen ein Teil mit einer Textbezeichnung Informationen für einen Teil ohne Text liefert, oder in denen sich ein Steuerelement in einer bekannten Bezeichnungsbeziehung zu einem anderen Steuerelement in der Benutzeroberfläche befinden soll. Wenn es möglich ist, ein nützliches, klassenbasiertes Verhalten bereitzustellen, können Sie GetLabeledByCore hierfür außer Kraft setzen.

GetBoundingRectangleCore und GetClickablePointCore werden hauptsächlich für automatisierte Testszenarien verwendet. Wenn Sie automatisierte Tests für Ihr Steuerelement unterstützen möchten, kann es ratsam sein, diese Methoden außer Kraft zu setzen. Dies kann für Bereichssteuerelemente nützlich sein, bei denen Sie keinen einzelnen Punkt vorschlagen können, weil sich abhängig von der Klickposition des Benutzers im Koordinatenbereich jeweils eine andere Auswirkung auf den Bereich ergibt. Beim standardmäßigen ScrollBar-Automatisierungspeer wird z. B. GetClickablePointCore außer Kraft gesetzt, um einen Wert vom Typ „"keine Zahl"Point“ zurückzugeben.

GetLiveSettingCore hat Einfluss auf den Steuerelement-Standardwert für den LiveSetting-Wert der Benutzeroberflächenautomatisierung. Das Außerkraftsetzen kann ratsam sein, wenn das Steuerelement einen anderen Wert als AutomationLiveSetting.Off zurückgeben soll. Weitere Informationen dazu, was LiveSetting darstellt, finden Sie unter AutomationProperties.LiveSetting.

Sie können GetOrientationCore außer Kraft setzen, falls das Steuerelement über eine Eigenschaft mit festlegbarer Ausrichtung verfügt, die AutomationOrientation zugeordnet werden kann. Dies ist mit den Klassen ScrollBarAutomationPeer und SliderAutomationPeer möglich.

Basisimplementierung in FrameworkElementAutomationPeer

Die Basisimplementierung von FrameworkElementAutomationPeer bietet einige Informationen zur Benutzeroberflächenautomatisierung, die von verschiedenen, auf der Frameworkebene definierten Layout- und Verhaltenseigenschaften interpretiert werden können.

  • GetBoundingRectangleCore: Gibt eine auf den bekannten Layouteigenschaften basierende Rect-Struktur zurück. Gibt einen 0-Wert Rect zurück, wenn IsOffscreen gleich true ist.
  • GetClickablePointCore: Gibt eine auf den bekannten Layouteigenschaften basierende Point-Struktur zurück, wenn ein BoundingRectangle ungleich Null vorhanden ist.
  • GetNameCore: Hier können umfangreichere Verhaltensweisen zusammengefasst werden (siehe GetNameCore). Im Grunde genommen wird versucht, eine Zeichenfolgekonvertierung für alle bekannten Inhalte einer ContentControl-Klasse oder verwandter Klassen, die über Inhalt verfügen, durchzuführen. Des Weiteren wird, wenn ein Wert für LabeledBy vorhanden ist, der Name-Wert dieses Elements als Name verwendet.
  • HasKeyboardFocusCore: Ausgewertet basierend auf den FocusState- und IsEnabled-Eigenschaften des Besitzers. Von Elementen, die keine Steuerelemente sind, wird immer false zurückgegeben.
  • IsEnabledCore: Ausgewertet basierend auf der IsEnabled-Eigenschaft des Besitzers, wenn es sich hierbei um ein Control handelt. Von Elementen, die keine Steuerelemente sind, wird immer true zurückgegeben. Dies bedeutet nicht, dass der Besitzer wie bei einer herkömmlichen Interaktion aktiviert wird, sondern dass der Peer aktiviert wird, obwohl der Besitzer nicht über eine IsEnabled-Eigenschaft verfügt.
  • IsKeyboardFocusableCore: Gibt true zurück, wenn der Besitzer ein Control ist. Andernfalls wird false zurückgegeben.
  • IsOffscreenCore: Ist der Wert für die Visibility für das Besitzerelement oder eines seiner übergeordneten Elemente Hidden, gleicht dies einem Wert von true für IsOffscreen. Ausnahme: ein Popup-Objekt kann sichtbar sein, auch wenn dies auf seine übergeordneten Elemente nicht zutrifft.
  • SetFocusCore: Ruft Focus auf.
  • GetParent: Ruft FrameworkElement.Parent vom Besitzer auf und sucht den entsprechenden Peer. Hierbei handelt es nicht um ein Außerkraftsetzungspaar mit einer "Core"-Methode. Daher können Sie dieses Verhalten nicht ändern.
Hinweis  Von Standard-Windows-Runtime-Peers wird ein Verhalten implementiert, indem der native Code verwendet wird, der die Windows-Runtime implementiert, und nicht unbedingt der tatsächliche Windows-Runtime-Code. Sie können den Code oder die Logik der Implementierung nicht mittels Common Language Runtime (CLR)-Spiegelung oder anderer Verfahren anzeigen. Außerdem sehen Sie keine einzelnen Referenzseiten in der Windows Runtime-Referenz für unterklassenspezifische Außerkraftsetzungen von Basispeerverhalten. Beispielsweise gibt es möglicherweise zusätzliche Verhaltensweisen für das GetNameCore-Element von TextBoxAutomationPeer, die nicht auf der AutomationPeer.GetNameCore-Referenzseite beschrieben ist, und es ist keine Referenzseite für TextBoxAutomationPeer.GetNameCore vorhanden. Es ist auch keine Referenzseite für TextBoxAutomationPeer.GetNameCore vorhanden. Lesen Sie stattdessen das Referenzthema für die am nächsten gelegene Peerklasse, und suchen Sie im Abschnitt „Anmerkungen“ nach Implementierungshinweisen.
 

Peers und "AutomationProperties"

Ihr Automatisierungspeer sollte entsprechende Standardwerte für die Informationen bereitstellen, die sich auf die Barrierefreiheit des Steuerelements beziehen. Beachten Sie, dass von jeglichem App-Code, der das Steuerelement nutzt, durch Einschließen der Werte der angefügten Eigenschaft AutomationProperties in die Steuerelementinstanzen ein Teil des Verhaltens außer Kraft gesetzt werden kann. Aufrufer können dies entweder für die Windows-Runtime-Standardsteuerelemente oder für benutzerdefinierte Steuerelemente tun. Mithilfe des folgenden XAML wird beispielsweise eine Schaltfläche erstellt, die über zwei angepasste Benutzeroberflächenautomatisierungs-Eigenschaften verfügt: <Button AutomationProperties.Name="Special" AutomationProperties.HelpText="This is a special button."/>

Weitere Informationen zu angefügten AutomationProperties-Eigenschaften finden Sie unter Bereitstellen von grundlegenden Informationen zu UI-Elementen.

Einige AutomationPeer-Methoden existieren aufgrund des allgemeinen Vertrags, der festlegt, wie Benutzeroberflächenautomatisierungs-Anbieter Informationen melden sollen, jedoch werden diese Methoden in der Regel aber nicht in Steuerelementpeers implementiert. Dies hat folgenden Grund: Es wird erwartet, dass die AutomationProperties-Werte, die auf den App-Code angewendet werden, der die Steuerelemente auf einer bestimmten UI verwendet, diese Informationen liefern. Die meisten Apps würden z. B. die Bezeichnungsbeziehung zwischen zwei verschiedenen Steuerelementen in der Benutzeroberfläche definieren, indem sie den Wert AutomationProperties.LabeledBy anwenden. LabeledByCore ist jedoch in bestimmten Peers implementiert, die Daten- oder Objektbeziehungen in einem Steuerelement darstellen, z. B. die Verwendung einer Headerkomponente zum Bezeichnen einer Datenfeldkomponente, Bezeichnen von Objekten mit ihren Containern oder ähnliche Szenarien.

Implementieren von Mustern

Als Nächstes wird beschrieben, wie ein Peer für ein Steuerelement geschrieben wird, mit dem durch die Implementierung der Steuerelement-Musterschnittstelle für Erweitern/Reduzieren das Verhalten zum Erweitern/Reduzieren implementiert wird. Der Peer sollte die Barrierefreiheit für das Verhalten zum Erweitern/Reduzieren ermöglichen, indem er jedes Mal, wenn GetPattern mit einem Wert von PatternInterface.ExpandCollapse aufgerufen wird, sich selbst zurückgibt. Dann sollte der Peer die Anbieterschnittstelle für dieses Muster (IExpandCollapseProvider) erben und Implementierungen für alle Member dieser Anbieterschnittstelle bereitstellen. In diesem Fall muss die Schnittstelle drei Member außer Kraft setzen: Expand, Collapse und ExpandCollapseState.

Es ist hilfreich, die Barrierefreiheit im API-Entwurf der Klasse selbst vorauszuplanen. Stellen Sie für ein Verhalten, das möglicherweise durch typische Benutzerinteraktionen mit der UI oder ein Automatisierungsanbietermuster angefordert wird, eine einzelne Methode bereit, die entweder als Benutzeroberflächenreaktion oder durch das Automatisierungsmuster aufgerufen werden kann. Beispiel: Ihr Steuerelement enthält Schaltflächenteile mit verknüpften Ereignishandlern, die das Steuerelement erweitern oder reduzieren können, sowie Tastaturentsprechungen für diese Aktionen. Sorgen Sie in diesem Fall dafür, dass diese Ereignishandler dieselbe Methode aufrufen, die von innerhalb der Expand- oder Collapse-Implementierung für IExpandCollapseProvider im Peer aufgerufen wird. Es kann auch nützlich sein, mit einer allgemeinen Logikmethode sicherzustellen, dass die visuellen Zustände Ihres Steuerelements aktualisiert werden, um den logischen Zustand einheitlich anzuzeigen, unabhängig davon, wie das Verhalten aufgerufen wurde.

Bei einer typischen Implementierung wird von den Anbieter-APIs zuerst der Owner aufgerufen, um Zugriff zur Laufzeit auf die Steuerelementinstanz zu erhalten. Danach können die erforderlichen Verhaltensmethoden für dieses Objekt aufgerufen werden.


public class IndexCardAutomationPeer : FrameworkElementAutomationPeer, IExpandCollapseProvider {
    private IndexCard ownerIndexCard;
    public IndexCardAutomationPeer(IndexCard owner) : base(owner) 
    { 
         ownerIndexCard = owner;
    } 
}

Eine andere Implementierungsmöglichkeit besteht darin, dass das Steuerelement selbst auf seinen Peer verweist. Dies ist ein häufig verwendetes Muster, wenn Automatisierungsereignisse über das Steuerelement ausgelöst werden, da die RaiseAutomationEvent-Methode eine Peermethode ist.

Benutzeroberflächenautomatisierungs-Ereignisse

Benutzeroberflächenautomatisierungs-Ereignisse werden in die folgenden Kategorien unterteilt.

EreignisBeschreibung
EigenschaftsänderungWird ausgelöst, wenn eine Eigenschaft eines Benutzeroberflächenautomatisierungs-Elements oder Steuerelementmusters geändert wird. Wenn ein Client beispielsweise das Steuerelement für das Kontrollkästchen einer App überwachen muss, kann dieser sich registrieren, um auf ein Eigenschaftsänderungsereignis im Hinblick auf die ToggleState-Eigenschaft zu lauschen. Wird das Steuerelement für das Kontrollkästchen aktiviert oder deaktiviert, wird das Ereignis vom Anbieter ausgelöst, und der Client kann die erforderliche Aktion ausführen.
Aktion für ElementWird ausgelöst, wenn durch eine Aktivität des Benutzers oder eine programmgesteuerte Aktivität eine Änderung der Benutzeroberfläche ausgelöst wird, beispielsweise wenn über das Muster Invoke auf eine Schaltfläche geklickt oder diese aufgerufen wird.
StrukturänderungWird ausgelöst, wenn der Benutzeroberflächenautomatisierungs-Baum geändert wird. Die Struktur wird geändert, wenn neue Benutzeroberflächenelemente angezeigt, ausgeblendet oder vom Desktop entfernt werden.
Globale ÄnderungWird ausgelöst, wenn Aktionen ausgeführt werden, die den Client global betreffen, beispielsweise wenn der Fokus von einem Element auf ein anderes gewechselt wird oder wenn ein untergeordnetes Fenster geschlossen wird. Einige Ereignisse implizieren nicht unbedingt, dass sich der Status der Benutzeroberfläche geändert hat. Wenn der Benutzer beispielsweise zu einem Texteingabefeld navigiert und dann auf eine Schaltfläche klickt, um das Feld zu aktualisieren, wird auch dann ein TextChanged-Ereignis ausgelöst, wenn der Benutzer den Text nicht geändert hat. Bei der Verarbeitung eines Ereignisses ist es u. U. erforderlich, von einer Clientanwendung überprüfen zu lassen, ob Änderungen vorliegen, bevor Maßnahmen ergriffen werden.

 

AutomationEvents-Bezeichner

Benutzeroberflächenautomatisierungs-Ereignisse werden durch AutomationEvents-Werte identifiziert. Durch die Werte der Enumeration wird die Art des Ereignisses eindeutig identifiziert.

Auslösen von Ereignissen

Benutzeroberflächenautomatisierungs-Clients können Automatisierungsereignisse abonnieren. Im Automatisierungspeermodell müssen Peers für benutzerdefinierte Steuerelemente Änderungen am Zustand des Steuerelements, die für die Barrierefreiheit relevant sind, durch den Aufruf der RaiseAutomationEvent-Methode melden. Entsprechend sollten die Peers des benutzerdefinierten Steuerelements die RaisePropertyChangedEvent-Methode aufrufen, wenn sich der Wert einer wichtigen Benutzeroberflächenautomatisierungs-Eigenschaft ändert.

Das folgende Codebeispiel zeigt, wie das Peerobjekt aus dem Steuerelement-Definitionscode abgerufen und eine Methode aufgerufen wird, um von diesem Peer aus ein Ereignis auszulösen. Zur Optimierung stellt der Code fest, ob es Listener für diesen Ereignistyp gibt. Wenn das Ereignis nur ausgelöst und das Peerobjekt nur erstellt wird, sofern Listener vorhanden sind, entsteht kein unnötiger Aufwand, und das Steuerelement bleibt reaktionsfähig.


if (AutomationPeer.ListenerExists(AutomationEvents.PropertyChanged))
{
    NumericUpDownAutomationPeer peer =
        FrameworkElementAutomationPeer.FromElement(nudCtrl) as NumericUpDownAutomationPeer;
    if (peer != null)
    {
        peer.RaisePropertyChangedEvent(
            RangeValuePatternIdentifiers.ValueProperty,
            (double)oldValue,
            (double)newValue);
    }
}

Peernavigation

Nachdem ein Automatisierungspeer gefunden wurde, kann ein Benutzeroberflächenautomatisierungs-Client in der Peerstruktur einer App navigieren, indem die Methoden GetChildren und GetParent des Peerobjekts aufgerufen werden. Die Navigation zwischen UI-Elementen in einem Steuerelement wird von der Implementierung der GetChildrenCore-Methode des Peers unterstützt. Das Benutzeroberflächenautomatisierungs-System ruft diese Methode auf, um eine Struktur der Unterelemente zu erstellen, die in einem Steuerelement enthalten sind, z. B. Listenelemente in einem Listenfeld. Die GetChildrenCore-Standardmethode in FrameworkElementAutomationPeer durchläuft die visuelle Struktur der Elemente, um die Struktur der Automatisierungspeers zu erstellen. Benutzerdefinierte Steuerelemente können diese Methode überschreiben, um eine andere Darstellung der untergeordneten Elemente für Automatisierungsclients verfügbar zu machen. Dabei werden die Automatisierungspeers der Elemente zurückzugeben, die Informationen übermitteln oder Benutzerinteraktion erlauben.

Systemeigene Automatisierungsunterstützung für Textmuster

Einige der Standard-Automatisierungspeers für Windows-Runtime-Apps bieten Unterstützung für Steuerelementmuster (PatternInterface.Text). Diese Unterstützung erfolgt aber über systemeigene Methoden, sodass die betroffenen Peers nicht die ITextProvider-Schnittstelle in der (verwalteten) Vererbung benachrichtigen. Wenn ein verwalteter oder nicht verwalteter Benutzeroberflächenautomatisierungs-Client den Peer nach Mustern abfragt, wird dieser trotzdem die Unterstützung des Textmusters melden und Teile des Musters bearbeiten, wenn die Client-APIs aufgerufen werden.

Wenn Sie von einem Textsteuerelement einer Windows-Runtime-App ableiten möchten, können Sie auch einen benutzerdefinierten Peer erstellen, der von einem der textspezifischen Peers abgeleitet ist. Im Abschnitt "Anmerkungen" des Peers finden Sie weitere Informationen zur möglichen systemeigenen Unterstützung von Mustern. Der Zugriff auf das systemeigene Verhalten Ihres benutzerdefinierten Peers erfolgt durch den Aufruf der Basisimplementierung Ihrer verwalteten Anbieterschnittstellenimplementierungen. es ist aber schwierig, das Verhalten der Basisimplementierung zu ändern, da die systemeigenen Schnittstellen weder im Peer noch im Eigentümersteuerelement verfügbar gemacht werden. Sie sollten im Allgemeinen entweder die Basisimplementierungen wie bereitgestellt verwenden (durch Aufruf der Basis) oder die Funktionen vollständig im eigenen verwalteten Code ersetzen und die Basisimplementierung gar nicht aufrufen. Im letzten Fall handelt es sich um ein fortgeschrittenes Szenario. Sie müssen mit dem von Ihrem Steuerelement verwendeten Textdienstframework vertraut sein, um die Anforderungen hinsichtlich der Barrierefreiheit zu unterstützen, wenn Sie dieses Framework verwenden.

AutomationProperties.AccessibilityView

Zusätzlich zum Bereitstellen eines benutzerdefinierten Peers können Sie auch die Strukturansichtdarstellung für beliebige Steuerelementinstanzen anpassen, indem Sie im XAML-Code AutomationProperties.AccessibilityView festlegen. Dieses Element wird nicht als Teil einer Peerklasse implementiert, aber es wird hier erwähnt, weil es für die allgemeine Barrierefreiheitsunterstützung für benutzerdefinierte Steuerelemente oder von Ihnen angepasste Vorlagen relevant ist.

Das Hauptszenario zur Verwendung von AutomationProperties.AccessibilityView ist das absichtliche Weglassen bestimmter Steuerelemente in einer Vorlage aus den Benutzeroberflächenautomatisierungs-Ansichten, weil sie keinen nennenswerten Beitrag zur Barrierefreiheitsansicht des gesamten Steuerelements leisten. Legen Sie AutomationProperties.AccessibilityView auf "Raw" fest, um dies zu verhindern. Weitere Informationen finden Sie unter AutomationProperties.AccessibilityView.

Auslösen von Ausnahmen über Automatisierungspeers

Die APIs, die Sie für Ihre Automatisierungspeerunterstützung implementieren, dürfen Ausnahmen auslösen. Es wird erwartet, dass lauschende Benutzeroberflächenautomatisierungs-Clients stabil genug sind, um nach dem Auslösen der meisten Ausnahmen weiter zu funktionieren. Aller Wahrscheinlichkeit nach betrachtet der Listener eine Automatisierungsgesamtstruktur, die neben Ihrer eigenen App auch andere Apps enthält. Das Clientdesign darf nicht zum Ausfall des gesamten Clients führen, wenn beim Aufrufen der APIs in einem Bereich der Struktur eine peerbasierte Ausnahme ausgelöst wird.

Parameter, die an Ihren Peer übergeben werden, können die Eingabe überprüfen und zum Beispiel ArgumentNullException auslösen, wenn null übergeben wurde und dies für Ihre Implementierung kein gültiger Wert ist. Wenn aber nachfolgende Vorgänge von Ihrem Peer ausgeführt werden, denken Sie daran, dass die Interaktionen des Peers mit dem hostenden Steuerelement einen gewissen asynchronen Charakter haben können. Durch Aktionen eines Peers wird nicht zwangsläufig der Benutzeroberflächenthread im Steuerelement blockiert (dies sollte vermutlich auch nicht geschehen). Daher sind Situationen denkbar, in denen ein Objekt bei der Erstellung des Peers oder beim ersten Aufruf einer Automatisierungspeermethode verfügbar war oder bestimmte Eigenschaften hatte, während sich der Zustand des Steuerelements in der Zwischenzeit geändert hat. Für diese Fälle gibt es zwei spezielle Ausnahmen, die ein Anbieter auslösen kann:

  • Lösen Sie ElementNotAvailableException aus, wenn Sie basierend auf den ursprünglich an Ihre APIs übergebenen Informationen nicht auf den Besitzer des Peers oder ein verwandtes Peerelement zugreifen können. Beispiel: Sie haben einen Peer, der seine Methoden auszuführen versucht. Der Besitzer wurde aber in der Zwischenzeit aus der Benutzeroberfläche entfernt. Dies ist z. B. der Fall, wenn ein modales Dialogfeld geschlossen wird. Bei einem Nicht-.NET-Client entspricht dies UIA_E_ELEMENTNOTAVAILABLE.
  • Lösen Sie ElementNotEnabledException aus, wenn noch ein Besitzer vorhanden ist, der sich aber in einem Modus wie zum Beispiel IsEnabled=false befindet, der einen Teil der spezifischen programmgesteuerten Änderungen blockiert, die der Peer vorzunehmen versucht. Bei einem Nicht-.NET-Client entspricht dies UIA_E_ELEMENTNOTENABLED.

Darüber hinaus sollten Peers mit Ausnahmen, die sie über die Peerunterstützung auslösen, relativ konservativ umgehen. Die meisten Clients können Ausnahmen von Peers nicht verarbeiten und wandeln diese in Wahlmöglichkeiten mit ausführbaren Aktionen um, die Benutzer bei Interaktionen mit dem Client auswählen können. Manchmal ist es also eine bessere Strategie, keinen Vorgang auszuführen und Ausnahmen ohne erneutes Auslösen in Ihren Peerimplementierungen abzufangen, als bei jeder fehlgeschlagenen Aktion des Peers Ausnahmen auszulösen. Berücksichtigen Sie auch, dass die meisten Benutzeroberflächenautomatisierungs-Clients nicht in verwaltetem Code geschrieben sind. Die meisten sind in COM geschrieben und suchen nur nach S_OK in einem HRESULT, wenn sie eine Benutzeroberflächenautomatisierungs-Clientmethode aufrufen, die letztendlich auf Ihren Peer zugreift.

Weitere Informationen zu Ausnahmen, vor allem zum Abfangen von Ausnahmen und zu den anschließenden Schritten, finden Sie unter Ausnahmebehandlung für Windows Store-Apps in C# oder Visual Basic.

Verwandte Themen

Barrierefreiheit für Windows-Runtime-Apps mit C#/VB/C++ und XAML
XAML-Beispiel für Barrierefreiheit
FrameworkElementAutomationPeer
AutomationPeer
OnCreateAutomationPeer
Steuerelementmuster und Schnittstellen

 

 

Anzeigen:
© 2017 Microsoft