Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier les répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer de répertoire.
UI Automation fournit une interface unique et généralisée que les clients Automation peuvent utiliser pour examiner ou exploiter les interfaces utilisateur de diverses plateformes et infrastructures. UI Automation permet à la fois le code d’assurance qualité (test) et les applications d’accessibilité, telles que les lecteurs d’écran, d’examiner les éléments de l’interface utilisateur et de simuler l’interaction utilisateur avec eux à partir d’autres codes. Pour plus d’informations sur UI Automation sur toutes les plateformes, consultez Accessibilité.
Cette rubrique explique comment implémenter un fournisseur UI Automation côté serveur pour un contrôle personnalisé qui s’exécute dans une application WPF. WPF prend en charge l'automation de l'interface utilisateur par le biais d'une arborescence d'objets d'automatisation similaires qui est parallèle à l'arborescence des éléments de l'interface utilisateur. Le code de test et les applications qui fournissent des fonctionnalités d’accessibilité peuvent utiliser des objets homologues Automation directement (pour le code in-process) ou via l’interface généralisée fournie par UI Automation.
Classes de pair d'automatisation
Les contrôles WPF prennent en charge UI Automation via une arborescence de classes homologues qui dérivent de AutomationPeer. Par convention, les noms de classes homologues commencent par le nom de la classe de contrôle et se terminent par « AutomationPeer ». Par exemple, ButtonAutomationPeer est la classe homologue de la Button classe de contrôle. Les classes homologues sont à peu près équivalentes aux types de contrôle UI Automation, mais sont spécifiques aux éléments WPF. Le code Automation qui accède aux applications WPF via l’interface UI Automation n’utilise pas directement des homologues Automation, mais le code automation dans le même espace de processus peut utiliser directement des homologues Automation.
Classes d'Automation Peer intégrées
Un élément implémente une classe de pair d'automatisation s'il accepte des interactions avec l'interface de l'utilisateur ou s'il contient des informations nécessaires aux utilisateurs d'applications de lecture d'écran. Tous les éléments visuels WPF n’ont pas tous des homologues d’automatisation. Exemples de classes qui implémentent des homologues d’automatisation sont Button, TextBoxet Label. Des exemples de classes qui n’implémentent pas d’homologues d’automatisation sont des classes qui dérivent de Decorator, telles que Border, et des classes basées sur Panel, telles que Grid et Canvas.
La classe de base Control n’a pas de classe homologue correspondante. Si vous avez besoin d’une classe homologue pour correspondre à un contrôle personnalisé qui dérive de Control, vous devez dériver la classe d’homologue personnalisée à partir de FrameworkElementAutomationPeer.
Considérations relatives à la sécurité pour les homologues dérivés
Les homologues d’automatisation doivent s’exécuter dans un environnement de confiance partielle. Le code de l’assembly UIAutomationClient n’est pas configuré pour s’exécuter dans un environnement de confiance partielle, et le code homologue Automation ne doit pas référencer cet assembly. Au lieu de cela, vous devez utiliser les classes dans l’assembly UIAutomationTypes. Par exemple, vous devez utiliser la AutomationElementIdentifiers classe de l’assembly UIAutomationTypes, qui correspond à la AutomationElement classe dans l’assembly UIAutomationClient. Il est sûr de référencer l’assembly UIAutomationTypes dans le code homologue Automation.
Navigation par les pairs
Après avoir localisé un pair automation, le code en cours de traitement peut naviguer dans l’arborescence du pair en appelant les méthodes de l'objet GetChildren et GetParent. La navigation entre les éléments WPF au sein d’un contrôle est prise en charge par l’implémentation de la GetChildrenCore méthode par l’homologue. Le système UI Automation appelle cette méthode pour créer une arborescence de sous-éléments contenus dans un contrôle ; par exemple, les éléments de liste dans une zone de liste. La méthode par défaut UIElementAutomationPeer.GetChildrenCore traverse l’arborescence visuelle des éléments pour générer l’arborescence des homologues d’automatisation. Les contrôles personnalisés remplacent cette méthode pour exposer les éléments enfants aux clients d'automatisation, renvoyant les homologues d'automatisation des éléments qui fournissent des informations ou permettent l'interaction utilisateur.
Personnalisations dans un homologue dérivé
Toutes les classes qui dérivent de UIElement et ContentElement contiennent la méthode protégée virtuelle OnCreateAutomationPeer. WPF appelle OnCreateAutomationPeer pour obtenir l’objet Automation homologue de chaque contrôle. Le code Automation peut utiliser l’homologue pour obtenir des informations sur les caractéristiques et fonctionnalités d’un contrôle et pour simuler une utilisation interactive. Un contrôle personnalisé qui prend en charge l’automatisation doit remplacer OnCreateAutomationPeer et retourner une instance d’une classe qui dérive de AutomationPeer. Par exemple, si un contrôle personnalisé dérive de la ButtonBase classe, l’objet retourné par OnCreateAutomationPeer doit dériver de ButtonBaseAutomationPeer.
Lors de l’implémentation d’un contrôle personnalisé, vous devez remplacer les méthodes 'Core' de la classe de base de l'homologue d'automatisation qui décrivent le comportement unique et spécifique de votre contrôle.
Redéfinir OnCreateAutomationPeer
Remplacez la OnCreateAutomationPeer méthode de votre contrôle personnalisé afin qu’il retourne votre objet fournisseur, qui doit dériver directement ou indirectement de AutomationPeer.
Remplacer GetPattern
Les homologues Automation simplifient certains aspects de l’implémentation des fournisseurs UI Automation côté serveur, mais les homologues d’automatisation de contrôle personnalisé doivent toujours gérer les interfaces de modèle. Comme les fournisseurs non WPF, les homologues prennent en charge les modèles de contrôle en fournissant des implémentations d’interfaces dans l'espace de noms System.Windows.Automation.Provider, telles que IInvokeProvider. Les interfaces de modèle de contrôle peuvent être implémentées par l’homologue lui-même ou par un autre objet. L’implémentation du pair retourne l’objet GetPattern qui prend en charge le modèle spécifié. Le code UI Automation appelle la GetPattern méthode et spécifie une PatternInterface valeur d’énumération. Votre remplacement de GetPattern doit renvoyer l’objet qui met en œuvre le modèle spécifié. Si votre contrôle n’a pas d’implémentation personnalisée d’un modèle, vous pouvez appeler l’implémentation du type de base pour GetPattern récupérer son implémentation ou sa valeur Null si le modèle n’est pas pris en charge pour ce type de contrôle. Par exemple, un contrôle NumericUpDown personnalisé peut définir une valeur dans un intervalle, de sorte que son pair UI Automation implémente l'interface IRangeValueProvider. L’exemple suivant montre comment la méthode de l’homologue GetPattern est substituée pour répondre à une valeur PatternInterface.RangeValue.
public override object GetPattern(PatternInterface patternInterface)
{
if (patternInterface == PatternInterface.RangeValue)
{
return this;
}
return base.GetPattern(patternInterface);
}
Public Overrides Function GetPattern(ByVal patternInterface As PatternInterface) As Object
If patternInterface = PatternInterface.RangeValue Then
Return Me
End If
Return MyBase.GetPattern(patternInterface)
End Function
Une GetPattern méthode peut également spécifier un sous-élément en tant que fournisseur de modèles. Le code suivant montre comment ItemsControl transfère la gestion des modèles de défilement vers l’homologue de son contrôle interne ScrollViewer .
public override object GetPattern(PatternInterface patternInterface)
{
if (patternInterface == PatternInterface.Scroll)
{
ItemsControl owner = (ItemsControl) base.Owner;
// ScrollHost is internal to the ItemsControl class
if (owner.ScrollHost != null)
{
AutomationPeer peer = UIElementAutomationPeer.CreatePeerForElement(owner.ScrollHost);
if ((peer != null) && (peer is IScrollProvider))
{
peer.EventsSource = this;
return (IScrollProvider) peer;
}
}
}
return base.GetPattern(patternInterface);
}
Public Class Class1
Public Overrides Function GetPattern(ByVal patternInterface__1 As PatternInterface) As Object
If patternInterface1 = PatternInterface.Scroll Then
Dim owner As ItemsControl = DirectCast(MyBase.Owner, ItemsControl)
' ScrollHost is internal to the ItemsControl class
If owner.ScrollHost IsNot Nothing Then
Dim peer As AutomationPeer = UIElementAutomationPeer.CreatePeerForElement(owner.ScrollHost)
If (peer IsNot Nothing) AndAlso (TypeOf peer Is IScrollProvider) Then
peer.EventsSource = Me
Return DirectCast(peer, IScrollProvider)
End If
End If
End If
Return MyBase.GetPattern(patternInterface1)
End Function
End Class
Pour spécifier un sous-élément pour la gestion des modèles, ce code obtient l’objet de sous-élément, crée un homologue à l’aide de la CreatePeerForElement méthode, définit la EventsSource propriété du nouvel homologue sur l’homologue actuel et retourne le nouvel homologue. La définition EventsSource d’un sous-élément empêche l’affichage du sous-élément dans l’arborescence d’homologues Automation et désigne tous les événements déclenchés par le sous-élément comme provenant du contrôle spécifié dans EventsSource. Le ScrollViewer contrôle n’apparaît pas dans l’arborescence d'automatisation et les événements de défilement qu'il génère semblent provenir de l’objet ItemsControl.
Remplacer les méthodes « Core »
Le code Automation obtient des informations sur votre contrôle en appelant des méthodes publiques de la classe homologue. Pour fournir des informations sur votre contrôle, remplacez chaque méthode dont le nom se termine par « Core » lorsque votre implémentation de contrôle diffère de celle fournie par la classe homologue Automation de base. Au minimum, votre contrôle doit implémenter les méthodes GetClassNameCore et GetAutomationControlTypeCore, comme illustré dans l’exemple suivant.
protected override string GetClassNameCore()
{
return "NumericUpDown";
}
protected override AutomationControlType GetAutomationControlTypeCore()
{
return AutomationControlType.Spinner;
}
Protected Overrides Function GetClassNameCore() As String
Return "NumericUpDown"
End Function
Protected Overrides Function GetAutomationControlTypeCore() As AutomationControlType
Return AutomationControlType.Spinner
End Function
Votre implémentation de GetAutomationControlTypeCore décrit votre contrôle en retournant une ControlType valeur. Bien que vous puissiez retourner ControlType.Custom, vous devriez renvoyer l’un des types de contrôle les plus spécifiques s’il décrit avec précision votre contrôle. Une valeur de retour de ControlType.Custom nécessite un travail supplémentaire pour que le fournisseur d'accès implémente UI Automation, et les produits clients UI Automation ne peuvent pas anticiper la structure de contrôle, l'interaction clavier et les modèles de contrôle possibles.
Implémentez les méthodes IsContentElementCore et IsControlElementCore pour indiquer si votre contrôle contient du contenu de données ou remplit un rôle interactif dans l'interface utilisateur (ou les deux). Par défaut, les deux méthodes retournent true. Ces paramètres améliorent la facilité d’utilisation des outils d’automatisation tels que les lecteurs d’écran, qui peuvent utiliser ces méthodes pour filtrer l’arborescence d’automatisation. Si la méthode GetPattern transfère la gestion des modèles à un homologue de sous-élément, la méthode du sous-élément voisin IsControlElementCore peut retourner false pour le masquer de l'arborescence d'automatisation. Par exemple, le défilement dans un ListBox est géré par un ScrollViewer, et l'homologue d'automatisation pour PatternInterface.Scroll est retourné par la méthode GetPattern du ScrollViewerAutomationPeer associé au ListBoxAutomationPeer. Par conséquent, la méthode IsControlElementCore de ScrollViewerAutomationPeer retourne false, afin que ScrollViewerAutomationPeer ne s’affiche pas dans l’arborescence d’automatisation.
Votre homologue d'automatisation doit fournir les valeurs par défaut appropriées pour votre contrôle. Notez que le code XAML qui référence votre contrôle peut remplacer vos implémentations de pairs de méthodes principales en incluant des attributs AutomationProperties. Par exemple, le code XAML suivant crée un bouton qui a deux propriétés UI Automation personnalisées.
<Button AutomationProperties.Name="Special"
AutomationProperties.HelpText="This is a special button."/>
Implémenter des fournisseurs de modèles
Les interfaces implémentées par un fournisseur personnalisé sont explicitement déclarées si l’élément propriétaire dérive directement de Control. Par exemple, le code suivant déclare un homologue pour un Control qui implémente une valeur de plage.
public class RangePeer1 : FrameworkElementAutomationPeer, IRangeValueProvider { }
Public Class RangePeer1
Inherits FrameworkElementAutomationPeer
Implements IRangeValueProvider
End Class
Si le contrôle propriétaire dérive d’un type spécifique de contrôle tel que RangeBase, l’homologue peut être dérivé d’une classe homologue dérivée équivalente. Dans ce cas, l’homologue dérive de RangeBaseAutomationPeer, qui fournit une implémentation de base de IRangeValueProvider. Le code suivant montre la déclaration d’un tel homologue.
public class RangePeer2 : RangeBaseAutomationPeer { }
Public Class RangePeer2
Inherits RangeBaseAutomationPeer
End Class
Pour obtenir un exemple d’implémentation, consultez le code source C# ou Visual Basic qui implémente et consomme un contrôle personnalisé NumericUpDown.
Déclencher des événements
Les clients Automation peuvent s’abonner à des événements Automation. Les contrôles personnalisés doivent signaler les modifications apportées à l’état de contrôle en appelant la RaiseAutomationEvent méthode. De même, lorsqu’une valeur de propriété change, appelez la RaisePropertyChangedEvent méthode. Le code suivant montre comment obtenir l’objet homologue à partir du code de contrôle et appeler une méthode pour déclencher un événement. En guise d’optimisation, le code détermine s’il existe des écouteurs pour ce type d’événement. Déclencher l’événement uniquement lorsqu’il y a des auditeurs évite une surcharge inutile et aide le contrôle à rester réactif.
if (AutomationPeer.ListenerExists(AutomationEvents.PropertyChanged))
{
NumericUpDownAutomationPeer peer =
UIElementAutomationPeer.FromElement(nudCtrl) as NumericUpDownAutomationPeer;
if (peer != null)
{
peer.RaisePropertyChangedEvent(
RangeValuePatternIdentifiers.ValueProperty,
(double)oldValue,
(double)newValue);
}
}
If AutomationPeer.ListenerExists(AutomationEvents.PropertyChanged) Then
Dim peer As NumericUpDownAutomationPeer = TryCast(UIElementAutomationPeer.FromElement(nudCtrl), NumericUpDownAutomationPeer)
If peer IsNot Nothing Then
peer.RaisePropertyChangedEvent(RangeValuePatternIdentifiers.ValueProperty, CDbl(oldValue), CDbl(newValue))
End If
End If
Voir aussi
.NET Desktop feedback