Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Den här artikeln beskriver automationskolleger i Microsoft UI Automation och hur du tillhandahåller robust automatiseringsstöd för anpassade användargränssnittsklasser.
Anmärkning
Den här vägledningen använder WinUI 3/Windows App SDK namnområden och referenser baserat på Microsoft. UI. Xaml.Automation.Peers.AutomationPeer.
UI Automation tillhandahåller ett ramverk som används av automationsklienter för att inspektera och interagera med användargränssnittet på olika plattformar. I Windows appar har de flesta inbyggda kontroller redan stöd för UI Automation. När du härleder en ny kontroll- eller supporttyp från befintliga icke-förseglade klasser kan du introducera beteenden som inte representeras av standard peer. I så fall utökar du automationsstödet genom att härleda från motsvarande AutomationPeer, lägga till det obligatoriska providerbeteendet och se till att kontrollinfrastrukturen skapar din peer.
UI Automation stöder både hjälpmedelsverktyg (till exempel skärmläsare) och automatiserade testsystem. I båda scenarierna kan extern kod inspektera gränssnittselement och simulera interaktion med din app. Mer information om plattformar finns i UI Automation Overview.
För team som prioriterar tillgänglighet och automatiserad testning är automationskollegor också ett tillförlitlighetskontrakt. Stabil automatiseringsstruktur och korrekt mönsterstöd förbättrar både assistivt teknikbeteende och långsiktig teststabilitet.
Det finns två primära målgrupper för UI Automation.
- UI Automation clients anropa UI Automation API:er för att identifiera och interagera med det aktuella tillgängliga användargränssnittet. En skärmläsare är till exempel en UI Automation-klient. Klienter navigerar i ett träd med automatiseringselement och kan rikta in sig på en app eller det fullständiga skrivbordsträdet.
- UI Automation providers förmedlar information i trädet genom att implementera API:er för kontroller som appen introducerar. När du skapar en anpassad kontroll deltar du i providermodellen och bör se till att din kontroll kan användas av både tillgänglighets- och testklienter.
Ramverket exponerar vanligtvis parallella API-ytor: en för klienter och en för leverantörer. Det här avsnittet fokuserar på utökningsbarhet för leverantörer, särskilt peer-klasser och providergränssnitt. API:er på klientsidan refereras endast till för kontext. För klientvägledning, se UI Automation Client Programmer's Guide.
Anmärkning
UI Automation klienter är vanligtvis skrivbordsappar och använder vanligtvis inte hanterad kod. UI Automation baseras på en standard och inte på en specifik implementering eller ett visst ramverk. Många befintliga UI Automation-klienter, inklusive hjälpteknikprodukter som skärmläsare, använder COM-gränssnitt (Component Object Model) för att interagera med UI Automation, systemet och de appar som körs i underordnade fönster. Mer information om COM-gränssnitten och hur du skriver en UI Automation-klient med COM finns i UI Automation Fundamentals.
Fastställa det befintliga tillståndet för UI Automation stöd för din anpassade användargränssnittsklass
Innan du implementerar en anpassad automations peer kontrollerar du om baskontrollen och dess peer redan har den support du behöver. I många fall är FrameworkElementAutomationPeer, kontrollspecifika peers och deras inbyggda mönster tillräckliga. Behovet av anpassning beror på hur mycket kontrollen avviker från basobjektmodellen och om mall- eller interaktionsändringar medför en ny användarupplevelse som kräver ytterligare hjälpmedelsstöd.
Som en del av den här utvärderingen kontrollerar du att standardbeteendet för peer är tillräckligt för dina automatiserade tillgänglighetstester, inte bara manuell kontroll. Om dina testscenarier är beroende av specifika mönster, namn eller hierarki implementerar du en anpassad peer så att dessa förväntningar förblir explicita och underhållsbara.
Även om basbeteendet är funktionellt acceptabelt rekommenderar vi fortfarande att du definierar din egen peer när exakt ClassName-rapportering är viktig för automatisering och testtillförlitlighet, särskilt för kontroller som är avsedda för återanvändning av andra.
Automation-peerklasser
WinUI och relaterade XAML-ramverk bygger på etablerade UI Automation konventioner från tidigare hanterade användargränssnittsstackar som Windows Forms, WPF och Silverlight. Många kontroll- och peer-begrepp följer dessa etablerade mönster.
Enligt konventionen börjar peer-klassnamn med kontrollklassnamnet och slutar med "AutomationPeer". ButtonAutomationPeer är till exempel peer-klassen för klassen Knappkontroll.
Anmärkning
I det här avsnittet behandlar vi de egenskaper som är relaterade till tillgänglighet som viktigare när du implementerar en kontroll-peer. Men för ett mer allmänt koncept för UI Automation support bör du implementera en peer i enlighet med rekommendationer som beskrivs i UI Automation Provider Programmer's Guide och UI Automation Fundamentals. De här avsnitten beskriver inte de specifika API:erna AutomationPeer som du använder i WinUI och Windows App SDK, men de beskriver de egenskaper som identifierar din klass eller ger annan information eller interaktion.
Peer-datorer, mönster och kontrolltyper
Ett kontrollmönster är en gränssnittsimplementering som exponerar en viss aspekt av en kontrolls funktioner för en UI Automation klient. UI Automation klienter använder de egenskaper och metoder som exponeras via ett kontrollmönster för att hämta information om funktionerna i kontrollen eller för att ändra kontrollens beteende vid körning.
Kontrollmönster exponerar beteendet oberoende av en kontrolls visuella objekt eller en specifik klassidentitet. En tabellkontroll kan till exempel exponera Rutnät så att klienter kan fråga efter dimensioner och hämta objekt. Klienter kan använda Invoke för anropande kontroller (till exempel knappar) och Rulla för rullningsbara ytor (till exempel listkontroller). Mönster är sammansättningsbara, så en enda kontroll kan exponera flera beteenden.
Kontrollmönster relaterar till användargränssnittet eftersom gränssnitten är relaterade till COM-objekt. I COM kan du fråga ett objekt för att fråga vilka gränssnitt det stöder och sedan använda dessa gränssnitt för att få åtkomst till funktioner. I UI Automation kan UI Automation klienter köra frågor mot ett UI Automation-element för att ta reda på vilka kontrollmönster det stöder och sedan interagera med elementet och dess peer-kopplade kontroll via egenskaper, metoder, händelser och strukturer som exponeras av de kontrollmönster som stöds.
Ett av automationskollegans primära ansvarsområden är att deklarera vilka mönster som stöds. Leverantörer gör detta genom att åsidosätta GetPatternCore, som stöder GetPattern. Klienter kör frågor mot ett mönster i taget. Om det stöds returnerar peer-objektet (vanligtvis sig självt), annars returneras null.
En kontrolltyp klassificerar i stort sett de funktioner som representeras av peer-filen. Detta skiljer sig från ett kontrollmönster: mönster beskriver specifika funktioner, medan kontrolltypen beskriver rollen på högre nivå. Varje kontrolltyp har vägledning för följande områden:
- UI Automation kontrollmönster: En kontrolltyp kan ha stöd för fler än ett mönster, som var och en representerar en annan klassificering av information eller interaktion. Varje kontrolltyp har en uppsättning kontrollmönster som kontrollen måste stödja, en uppsättning som är valfri och en uppsättning som kontrollen inte får stödja.
- UI Automation egenskapsvärden: Varje kontrolltyp har en uppsättning egenskaper som kontrollen måste stödja. Det här är de allmänna egenskaperna, enligt beskrivningen i UI Automation Properties Overview, inte de som är mönsterspecifika.
- UI Automation händelser: Varje kontrolltyp har en uppsättning händelser som kontrollen måste stödja. Återigen är dessa allmänna, inte mönsterspecifika, enligt beskrivningen i UI Automation Händelseöversikt.
- UI Automation trädstruktur: Varje kontrolltyp definierar hur kontrollen måste visas i UI Automation trädstruktur.
Oavsett ramverksinformation är klientbeteendet inte kopplat till en specifik XAML-appmodell. Många befintliga klienter, inklusive hjälpmedelstekniker, interagerar via COM. I den modellen anropar klienterna QueryInterface för mönstergränssnitt eller allmänna automationsgränssnitt och automationsinfrastrukturens hanterar anrop till appens provider och peer-implementering.
När du implementerar kontrollmönster för en Windows app med hanterad kod kan du använda .NET-gränssnitt för att representera dessa mönster i stället för COM-gränssnittssyntax. Till exempel är UI Automation-mönstergränssnittet för en .NET providerimplementering av Invoke-mönstret IInvokeProvider.
En lista över kontrollmönster, providergränssnitt och deras syfte finns i Kontrollera mönster och gränssnitt. Kontrolltyper finns i UI Automation Översikt över kontrolltyper.
Vägledning för hur du implementerar kontrollmönster
Vägledning för kontrollmönster tillhör den övergripande UI Automation plattformen, inte bara till en specifik appmodell. När du implementerar mönster kan du anpassa beteendet efter Microsoft dokumentation och UI Automation konventioner. Börja med Implementing UI Automation Control Patterns, särskilt avsnitten implementering och nödvändiga medlemmar för varje mönster. Även om dessa referenser ofta beskriver interna COM-gränssnitt är motsvarande providergränssnitt tillgängliga för WinUI i Microsoft. UI. Xaml.Automation.Provider.
Om du använder standardautomatiseringskomponenter och utökar deras beteende, har dessa komponenter redan skrivits i enlighet med UI Automations riktlinjer. Om de stöder kontrollmönster kan du förlita dig på att mönsterstödet överensstämmer med vägledningen på Implementing UI Automation Control Patterns. Om en kontroll peer rapporterar att den är representativ för en kontrolltyp som definierats av UI Automation, har vägledningen som dokumenteras på Supporting UI Automation Control Types följts av peer-filen.
Ytterligare tolkning krävs ofta när du implementerar mönster eller kontrolltyper som inte omfattas av standardkontroller. XAML-standardkontroller implementerar till exempel inte anteckningsmönster. Om din app är beroende av anteckningsarbetsflöden kan din peer implementera IAnnotationProvider och rapportera en dokumentkontrolltyp med egenskaper som kommunicerar anteckningsfunktionen.
Vi rekommenderar att du använder den vägledning som du ser för mönstren under Implementing UI Automation Control Patterns eller kontrolltyper under Supporting UI Automation Control Types som orientering och allmän vägledning. API-länkarna innehåller beskrivningar och kommentarer om syftet med API:erna. För WinUI-syntaxen använder du motsvarande API i Microsoft. UI. Xaml.Automation.Provider namnrymd.
Inbyggda peer-klasser för automatisering
I allmänhet exponerar element automationskollegor när de är interaktiva eller ger meningsfull information till hjälpmedelstekniker. Alla visuella element behöver inte motsvarigheter. Till exempel har Button och TextBox jämnlikar, medan Kant- och panelbaserade layouttyper som Grid och Canvas inte gör det. En panel bidrar endast till layouten och har ingen direkt interaktionsmodell för tillgänglighet, så dess väsentliga underordnade element visas via den närmaste överordnade enheten som har en jämförbar struktur.
UI Automation processgränser
UI Automation-klienter som inspekterar Windows-appar körs vanligtvis utanför processen. UI Automation infrastruktur hanterar kommunikation mellan processer. Mer information finns i UI Automation Fundamentals.
OnCreateAutomationPeer
Alla klasser som härleds från UIElement innehåller den skyddade virtuella metoden OnCreateAutomationPeer. Objektinitieringssekvensen för automation peers anropar OnCreateAutomationPeer för att hämta peer-objektet för varje kontroll och därmed skapa ett UI Automation-träd för användning vid körning. UI Automation kod kan använda peer-filen för att hämta information om en kontrolls egenskaper och funktioner och simulera interaktiv användning med hjälp av dess kontrollmönster. En anpassad kontroll som stöder automatisering måste åsidosätta OnCreateAutomationPeer och returnera en instans av en klass som härleds från AutomationPeer. Om en anpassad kontroll till exempel härleds från klassen ButtonBase bör objektet som returneras av OnCreateAutomationPeer härledas från ButtonBaseAutomationPeer.
Om du skriver en anpassad kontroll och anger en anpassad peer åsidosätter du OnCreateAutomationPeer så att den returnerar en ny instans av din peer-typ. Peer-objektet måste härledas direkt eller indirekt från AutomationPeer.
Följande kod deklarerar till exempel att anpassad kontroll NumericUpDown använder NumericUpDownPeer för UI Automation.
using Microsoft.UI.Xaml.Automation.Peers;
...
public class NumericUpDown : RangeBase {
public NumericUpDown() {
// other initialization; DefaultStyleKey etc.
}
...
protected override AutomationPeer OnCreateAutomationPeer()
{
return new NumericUpDownAutomationPeer(this);
}
}
Public Class NumericUpDown
Inherits RangeBase
' other initialization; DefaultStyleKey etc.
Public Sub New()
End Sub
Protected Overrides Function OnCreateAutomationPeer() As AutomationPeer
Return New NumericUpDownAutomationPeer(Me)
End Function
End Class
// NumericUpDown.idl
namespace MyNamespace
{
runtimeclass NumericUpDown : Microsoft.UI.Xaml.Controls.Primitives.RangeBase
{
NumericUpDown();
Int32 MyProperty;
}
}
// NumericUpDown.h
...
struct NumericUpDown : NumericUpDownT<NumericUpDown>
{
...
Microsoft::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer()
{
return winrt::make<MyNamespace::implementation::NumericUpDownAutomationPeer>(*this);
}
};
//.h
public ref class NumericUpDown sealed : Microsoft::UI::Xaml::Controls::Primitives::RangeBase
{
// other initialization not shown
protected:
virtual AutomationPeer^ OnCreateAutomationPeer() override
{
return ref new NumericUpDownAutomationPeer(this);
}
};
Anmärkning
OnCreateAutomationPeer-implementeringen bör inte göra något annat än att initiera en ny instans av din anpassade automation-peer, skicka samtalskontrollen som ägare och returnera den instansen. Försök inte med ytterligare logik i den här metoden. I synnerhet kan all logik som potentiellt kan leda till förstörelse av AutomationPeer inom samma anrop leda till oväntat körningsbeteende.
I typiska OnCreateAutomationPeer-implementeringar är ägarendetta eller Jag, eftersom åsidosättningen körs inom kontrollinstansomfånget.
Du kan definiera peer-klasser i samma fil som kontrollen eller i separata filer. Ramverks peer-typer finns i Microsoft.UI.Xaml.Automation.Peers, men dina anpassade peer-element kan finnas i alla namnområden, förutsatt att nödvändiga namnområden refereras där OnCreateAutomationPeer implementeras.
Välja rätt peer-basklass
Härled din anpassade AutomationPeer från den närmaste peer-basklassen som matchar kontrollens funktionella basklass. I föregående exempel NumericUpDown härleds från RangeBase, så RangeBaseAutomationPeer är rätt peer-bas. På så sätt kan du återanvända befintligt IRangeValueProvider-beteende i stället för att implementera det igen.
Baskontrollklassen har ingen motsvarande peer-klass. Om du behöver en peer-klass för att motsvara en anpassad kontroll som härleds från Kontroll härleder du den anpassade peer-klassen från FrameworkElementAutomationPeer.
Om du härleder från ContentControl direkt har den klassen inget standardbeteende för automation peer eftersom det inte finns någon OnCreateAutomationPeer-implementering som refererar till en peer-klass. Så se till att antingen implementera OnCreateAutomationPeer för att använda din egen peer eller att använda FrameworkElementAutomationPeer som peer om den nivån av hjälpmedelsstöd är tillräcklig för din kontroll.
Anmärkning
Vanligtvis härleder du inte från AutomationPeer utan snarare från FrameworkElementAutomationPeer. Om du härledde direkt från AutomationPeer måste du duplicera en hel del grundläggande hjälpmedelsstöd som annars skulle komma från FrameworkElementAutomationPeer.
Initiering av en anpassad peer-klass
En anpassad peer ska exponera en typsäker konstruktor som tar ägarkontrollen och skickar den till basklassinitieraren. I nästa exempel owner skickas till RangeBaseAutomationPeer och slutligen använder FrameworkElementAutomationPeer det värdet för att ange FrameworkElementAutomationPeer.Owner.
public NumericUpDownAutomationPeer(NumericUpDown owner): base(owner)
{}
Public Sub New(owner As NumericUpDown)
MyBase.New(owner)
End Sub
// NumericUpDownAutomationPeer.idl
import "NumericUpDown.idl";
namespace MyNamespace
{
runtimeclass NumericUpDownAutomationPeer : Microsoft.UI.Xaml.Automation.Peers.AutomationPeer
{
NumericUpDownAutomationPeer(NumericUpDown owner);
Int32 MyProperty;
}
}
// NumericUpDownAutomationPeer.h
...
struct NumericUpDownAutomationPeer : NumericUpDownAutomationPeerT<NumericUpDownAutomationPeer>
{
...
NumericUpDownAutomationPeer(MyNamespace::NumericUpDown const& owner);
};
//.h
public ref class NumericUpDownAutomationPeer sealed : Microsoft::UI::Xaml::Automation::Peers::RangeBaseAutomationPeer
//.cpp
public: NumericUpDownAutomationPeer(NumericUpDown^ owner);
Grundläggande metoder för AutomationPeer
Åsidosättande automatiseringsmetoder exponeras som par: en offentlig metod som används av leverantörsinfrastrukturen och en skyddad Core metod som är avsedd för anpassning. Som standard vidarebefordrar den offentliga metoden till motsvarande Core metod och återgår till basimplementeringen när det behövs.
När du implementerar en peer för en anpassad kontroll åsidosätter Core du metoder där ditt beteende skiljer sig från grundläggande peer-beteende. UI Automation hämtar information via offentliga metoder, men anpassningspunkten är motsvarande Core överskrivning.
När du definierar en ny peer-klass implementerar du minst metoden GetClassNameCore , som du ser i nästa exempel.
protected override string GetClassNameCore()
{
return "NumericUpDown";
}
Anmärkning
Du kanske vill lagra strängarna som konstanter i stället för direkt i metodtexten, men det är upp till dig. För GetClassNameCore behöver du inte lokalisera den här strängen. Egenskapen LocalizedControlType används varje gång en lokaliserad sträng behövs av en UI Automation-klient, inte ClassName.
HämtaAutomationKontrolltyp
Vissa hjälpmedelstekniker rapporterar GetAutomationControlType tillsammans med UI Automation Name. Om kontrollens roll skiljer sig meningsfullt från basklassrollen implementerar du en anpassad peer och åsidosätter GetAutomationControlTypeCore. Detta är särskilt viktigt när du härleder från generaliserade baser som ItemsControl eller ContentControl.
Implementeringen av GetAutomationControlTypeCore beskriver din kontroll genom att returnera ett AutomationControlType-värde . Även om du kan returnera AutomationControlType.Custom bör du returnera en av de mer specifika kontrolltyperna om den beskriver kontrollens huvudscenarier korrekt. Här följer ett exempel.
protected override AutomationControlType GetAutomationControlTypeCore()
{
return AutomationControlType.Spinner;
}
Anmärkning
Om du inte anger AutomationControlType.Custom behöver du inte implementera GetLocalizedControlTypeCore för att ange ett LocalizedControlType-egenskapsvärde för klienter. Den gemensamma infrastrukturen för UI Automation tillhandahåller översatta strängar för alla möjliga AutomationControlType-värden utom AutomationControlType.Custom.
GetPattern och GetPatternCore
GetPatternCore returnerar objektet som stöder det begärda mönstret. En UI Automation-klient begär en specifik PatternInterface via GetPattern. Om det stöds bör åsidosättningen returnera implementeringsobjektet, vanligtvis själva peer-objektet. Om det inte stöds returnerar du null (ofta genom att delegera till basbeteendet och låta det returnera null).
När ett mönster stöds kan GetPatternCore returnera detta eller Mig. Klienterna omvandlar sedan GetPattern returvärde till det begärda gränssnittet.
Om en peer-klass ärver från en annan peer och all nödvändig support och mönsterrapportering redan hanteras av basklassen är det inte nödvändigt att implementera GetPatternCore . Om du till exempel implementerar en intervallkontroll som härleds från RangeBase och din peer härleds från RangeBaseAutomationPeer, returnerar den peern sig själv för PatternInterface.RangeValue och har fungerande implementeringar av gränssnittet IRangeValueProvider som stöder mönstret.
Även om det inte är den bokstavliga koden, beskriver det här exemplet ungefär implementeringen av GetPatternCore som redan finns i RangeBaseAutomationPeer.
protected override object GetPatternCore(PatternInterface patternInterface)
{
if (patternInterface == PatternInterface.RangeValue)
{
return this;
}
return base.GetPatternCore(patternInterface);
}
Om du implementerar en peer där du inte har allt stöd du behöver från en bas-peer-klass, eller om du vill ändra eller lägga till i uppsättningen med grundläggande ärvda mönster som din peer kan stödja, bör du åsidosätta GetPatternCore så att UI Automation klienter kan använda mönstren.
En lista över UI Automation providermönster som stöds av WinUI finns i Microsoft. UI. Xaml.Automation.Provider. Varje sådant mönster har motsvarande värde för PatternInterface uppräkning, vilket är hur UI Automation klienter begär mönstret i ett GetPattern-anrop.
En jämnlike kan rapportera att den stödjer mer än ett mönster. I så fall bör åsidosättningen innehålla retursökvägslogik för varje PatternInterface-värde som stöds och returnera peer-värdet i varje matchande fall. Det förväntas att anroparen endast begär ett gränssnitt i taget, och det är upp till anroparen att casta till det förväntade gränssnittet.
Här är ett exempel på en GetPatternCore-åsidosättning för en anpassad peer. Den rapporterar stöd för två mönster, IRangeValueProvider och IToggleProvider. Kontrollen här är en medievisningskontroll som kan visas som helskärmsläge (växlingsläget) och som har en förloppsindikator där användarna kan välja en position (intervallkontrollen). Den här koden kom från XAML-tillgänglighetsexemplet (arkiverat äldre exempel).
protected override object GetPatternCore(PatternInterface patternInterface)
{
if (patternInterface == PatternInterface.RangeValue)
{
return this;
}
else if (patternInterface == PatternInterface.Toggle)
{
return this;
}
return null;
}
Vidarebefordringsmönster från underelement
En GetPatternCore-metodimplementering kan också ange ett underelement eller en del som en mönsterleverantör för sin värd. Det här exemplet efterliknar hur ItemsControl överför rullningsmönsterhantering till peer-filen för den interna ScrollViewer-kontrollen . Om du vill ange ett underelement för mönsterhantering hämtar den här koden underelementsobjektet, skapar en peer för underelementet med hjälp av metoden FrameworkElementAutomationPeer.CreatePeerForElement och returnerar den nya peer-filen.
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);
}
Andra kärnmetoder
Kontrollen kan behöva tangentbordsalternativ för kärnscenarier. Mer information finns i Hjälpmedel för tangentbord. Nyckelbeteendet hör till kontrolllogik, men peer-datorn bör rapportera viktiga metadata via GetAcceleratorKeyCore och GetAccessKeyCore. Om viktiga beskrivningar är användarriktade kan du lokalisera dem via resurser.
Om kontrollen exponerar samlingar använder du funktionella och peer-basklasser som redan implementerar insamlingsbeteende. Annars åsidosätter du GetChildrenCore för att korrekt representera överordnade och underordnade relationer i automationsträdet.
Implementera IsContentElementCore och IsControlElementCore för att ange om din kontroll ska behandlas som innehåll, kontroll eller båda. Båda standard-inställningarna har värdet true. Dessa värden hjälper klienter som skärmläsare att filtrera och navigera i trädet effektivt. Om GetPatternCore vidarebefordrar beteendet till en peer för underelement kan underelementet returnera false från IsControlElementCore för att hålla sig borta från det exponerade trädet.
Vissa kontroller kan ha stöd för etiketteringsscenarier, där en textetikettdel tillhandahåller information för en icke-textdel eller en kontroll är avsedd att finnas i en känd etikettrelation med en annan kontroll i användargränssnittet. Om det är möjligt att tillhandahålla ett användbart klassbaserat beteende kan du åsidosätta GetLabeledByCore för att tillhandahålla det här beteendet.
GetBoundingRectangleCore och GetClickablePointCore används främst för automatiserade testscenarier. Om du vill stödja automatiserad testning för din kontroll kanske du vill åsidosätta dessa metoder. Detta kan vara önskvärt för kontroller av intervalltyp, där du inte bara kan föreslå en enda punkt eftersom där användaren klickar i koordinatutrymmet har en annan effekt på ett intervall. Till exempel åsidosätter standardScrollBar-automatiseringspeerGetClickablePointCore för att returnera ett "inte ett nummer" Point-värde.
GetLiveSettingCore påverkar standardvärdet för LiveSetting för UI Automation. Du kanske vill åsidosätta detta om du vill att kontrollen ska returnera ett annat värde än AutomationLiveSetting.Off. Mer information om vad LiveSetting representerar finns i AutomationProperties.LiveSetting.
Du kan åsidosätta GetOrientationCore om kontrollen har en inställningsbar orienteringsegenskap som kan mappas till AutomationOrientation. Klasserna ScrollBarAutomationPeer och SliderAutomationPeer gör detta.
Basimplementering i FrameworkElementAutomationPeer
FrameworkElementAutomationPeer-basimplementeringen tillhandahåller automatiseringsinformation som härleds från layout- och beteendetillstånd på ramverksnivå.
- GetBoundingRectangleCore: Returnerar en Rekt-struktur baserat på kända layoutegenskaper. Returnerar en rektangel med värdet 0 om IsOffscreen är sant.
- GetClickablePointCore: Returnerar en punktstruktur baserat på kända layoutegenskaper, så länge det finns en nonzero BoundingRectangle.
- GetNameCore: Mer omfattande beteende än vad som kan sammanfattas här; se GetNameCore. I grund och botten försöker den en strängkonvertering på alla kända innehåll i en ContentControl eller relaterade klasser som har innehåll. Om det finns ett värde för LabeledBy används objektets namnvärde som Namn.
- HasKeyboardFocusCore: Utvärderas baserat på ägarens egenskaper FocusState och IsEnabled . Element som inte är kontroller returnerar alltid false.
- IsEnabledCore: Utvärderas baserat på ägarens IsEnabled-egenskap om det är en kontroll. Element som inte är kontroller returnerar alltid sant. Det betyder inte att ägaren är aktiverad i konventionell interaktionsmening; det innebär att peeren är aktiverad trots att ägaren inte har en IsEnabled-egenskap.
- IsKeyboardFocusableCore: Returnerar true om ägaren är en Control; annars är det false.
- IsOffscreenCore: En synlighet för Komprimerad på ägarelementet eller någon av dess föräldrar motsvarar ett verkligt värde för IsOffscreen. Undantag: Ett popup-objekt kan vara synligt även om ägarens föräldrar inte är det.
- SetFocusCore: Anropar Fokus.
- GetParent: Anropar FrameworkElement.Parent från ägaren och letar upp lämplig peer. Det här är inte ett överlagringspar med en "Core"-metod, så du kan inte ändra den här funktionen.
Anmärkning
Standardramverkskolleger implementerar beteende med hjälp av intern intern kod, inte nödvändigtvis med hjälp av projicerad hanterad kod. Du kommer inte att kunna granska fullständig implementeringsinformation via CLR-reflektion (Common Language Runtime) eller liknande tekniker. Du ser inte heller distinkta referenssidor för underklassspecifika åsidosättningar av grundläggande peer-beteende. Det kan till exempel finnas ytterligare beteende för GetNameCore för en TextBoxAutomationPeer, som inte beskrivs på referenssidan AutomationPeer.GetNameCore , och det finns ingen dedikerad referenssida för TextBoxAutomationPeer.GetNameCore . Läs istället referensavsnittet för den närmast relaterade klassen och leta efter implementeringsanteckningar i avsnittet Kommentarer.
Jämlikar och AutomationEgenskaper
Din automationspartner bör tillhandahålla lämpliga standardvärden för tillgänglighetsmetadata. Du kan fortfarande åsidosätta delar av dessa metadata med AutomationEgenskaper kopplade egenskaper på kontrollinstanser. Detta gäller både inbyggda och anpassade kontroller. Till exempel: <Button AutomationProperties.Name="Special" AutomationProperties.HelpText="This is a special button."/>
Mer information om AutomationProperties kopplade egenskaper finns i grundläggande hjälpmedelsinformation.
Vissa AutomationPeer-metoder finns för att uppfylla allmänna leverantörskontrakt men anpassas sällan i kontrollpeers, eftersom appen vanligtvis tillhandahåller dessa uppgifter via AutomationProperties. Många appar etablerar till exempel etiketteringsrelationer med AutomationProperties.LabeledBy. LabeledByCore implementeras däremot vanligtvis endast i peer-datorer som modellerar interna objekt-/rubrikrelationer.
Implementera mönster
Överväg en kontroll som exponerar expandera och kollapsa beteende. Dess peer bör returnera sig själv när GetPattern efterfrågas för PatternInterface.ExpandCollapse, implementera IExpandCollapseProvider och definiera Expandera, Dölj och ExpanderaCollapseState.
Utforma hjälpmedel i själva kontroll-API:et. När beteende kan utlösas antingen av direkt interaktion med användargränssnittet eller av ett automatiseringsmönster dirigerar du båda sökvägarna via logik för delad kontroll. Om knapphanterare och tangentbordskommandon till exempel kan expandera/komprimera bör de anropa samma interna metoder som används av peer-implementeringar av Expandera och Dölj. Detta håller beteende- och visuella tillståndsövergångar konsekventa, oavsett anropssökväg.
En typisk implementering är att provider-API:erna först anropar Ägare för att få tillgång till kontrollinstansen under körning. Sedan kan de beteendemetoder som krävs anropas för objektet.
public class IndexCardAutomationPeer : FrameworkElementAutomationPeer, IExpandCollapseProvider {
private IndexCard ownerIndexCard;
public IndexCardAutomationPeer(IndexCard owner) : base(owner)
{
ownerIndexCard = owner;
}
}
En alternativ implementering är att själva kontrollen kan referera till sin peer. Det här är ett vanligt mönster om du höjer automationshändelser från kontrollen, eftersom metoden RaiseAutomationEvent är en peer-metod.
UI Automation händelser
UI Automation händelser delas vanligtvis in i dessa kategorier.
| Event | Beskrivning |
|---|---|
| Egenskapsändring | Utlöses när en egenskap på ett UI Automation element eller kontrollmönster ändras. Om en klient till exempel behöver övervaka en apps kryssrutekontroll kan den registrera sig för att lyssna efter en egenskapsändringshändelse på egenskapen ToggleState . När kryssrutan är markerad eller avmarkerad utlöser providern händelsen och klienten kan agera efter behov. |
| Elementåtgärd | Utlöses när en ändring i användargränssnittet beror på användar- eller programmatisk aktivitet. Till exempel när en knapp klickas eller anropas via mönstret Anropa . |
| Strukturändring | Utlöses när strukturen för UI Automation träd ändras. Strukturen ändras när nya gränssnittsobjekt blir synliga, dolda eller borttagna på skrivbordet. |
| Global förändring | Aktiveras när åtgärder av globalt intresse för klienten inträffar, till exempel när fokus flyttas från en komponent till en annan, eller när ett popup-fönster stängs. Vissa händelser innebär inte nödvändigtvis att användargränssnittets tillstånd har ändrats. Om användaren till exempel flikar till ett textinmatningsfält och sedan klickar på en knapp för att uppdatera fältet utlöses en TextChanged-händelse även om användaren inte faktiskt ändrade texten. När du bearbetar en händelse kan det vara nödvändigt för ett klientprogram att kontrollera om något faktiskt har ändrats innan du vidtar åtgärder. |
AutomationEvents-identifikatorer
UI Automation händelser identifieras av värdena AutomationEvents. Värdena för uppräkningen identifierar unikt typen av händelse.
Utlösa händelser
UI Automation klienter kan prenumerera på automationshändelser. I automatiseringsmodellens peer, måste peers för anpassade kontroller rapportera ändringar av kontrollens tillstånd som är relevanta för tillgänglighet genom att anropa metoden RaiseAutomationEvent. När ett viktigt UI Automation-egenskapsvärde ändras bör anpassade kontrollkamrater anropa metoden RaisePropertyChangedEvent.
I nästa kodexempel visas hur du hämtar peer-objektet inifrån kontrolldefinitionskoden och anropar en metod för att utlösa en händelse från den peer-peern. Som optimering avgör koden om det finns några lyssnare för den här händelsetypen. Att starta händelsen och skapa peer-objektet endast när det finns lyssnare undviker onödiga omkostnader och hjälper kontrollen att förbli dynamisk.
if (AutomationPeer.ListenerExists(AutomationEvents.PropertyChanged))
{
NumericUpDownAutomationPeer peer =
FrameworkElementAutomationPeer.FromElement(nudCtrl) as NumericUpDownAutomationPeer;
if (peer != null)
{
peer.RaisePropertyChangedEvent(
RangeValuePatternIdentifiers.ValueProperty,
(double)oldValue,
(double)newValue);
}
}
Peer-navigering
När du har hämtat en peer kan UI Automation-klienter navigera i appens peer-struktur genom att anropa GetChildren och GetParent. I en kontroll skapas barnnavigering av GetChildrenCore, som UI Automation använder för att bygga underträdet (till exempel objekt i en lista). Standardimplementeringen i FrameworkElementAutomationPeer passerar det visuella trädet. Anpassade kontroller kan åsidosätta detta för att exponera en mer meningsfull automatiseringsrepresentation.
Inbyggt automationsstöd för textmönster
Vissa standardramverkskollegor stöder textmönster (PatternInterface.Text) via intern implementeringsinformation, så ITextProvider kanske inte visas i hanterat arv. Trots detta kan mönsterfrågor från hanterade eller ohanterade klienter fortfarande rapportera stöd för textmönster och exponera motsvarande beteende.
Om du tänker härleda från en av textkontrollerna och även skapa en anpassad peer som härleds från en av de textrelaterade peerkontrollerna, kontrollerar du avsnitten Anmärkningar i API-referensen för att lära dig mer om inbyggt stöd för mönster. Du kan komma åt det interna basbeteendet i din anpassade peer om du anropar basimplementeringen från implementeringarna av det hanterade providergränssnittet, men det är svårt att ändra vad basimplementeringen gör eftersom de interna gränssnitten på både peer- och ägarkontrollen inte exponeras. Vanligtvis bör du antingen använda basimplementeringarna as-is (endast anropsbas) eller helt ersätta funktionen med din egen hanterade kod och inte anropa basimplementeringen. Det senare är ett avancerat scenario, och det kräver stark kännedom om det texttjänstramverk som används av din kontroll för att uppfylla tillgänglighetskraven.
AutomationEgenskaper.Tillgänglighetssyn
Förutom anpassade peers kan du justera representationen av automationsträd per instans av kontroll genom att ange AutomationProperties.AccessibilityView i XAML. Det här är inte peer-kod, men det är ofta viktigt när du förfinar tillgängligheten för anpassade mallar.
Det primära användningsfallet är att utelämna malldelar som inte bidrar med meningsfull tillgänglighetssemantik för den sammansatta kontrollen. Det gör du genom att ange AutomationProperties.AccessibilityView till "Raw".
Kastar undantag från automatiska jämförelseenheter
Peer-implementeringar kan utlösa undantag och robusta klienter förväntas fortsätta bearbetningen. I praktiken inspekterar klienter ofta automatiseringsträd som sträcker sig över flera appar, så fel i ett underträd bör inte avsluta klientprocessen.
Indataverifiering är lämpligt. Du kan till exempel utlösa ArgumentNullException när null är ogiltigt för implementeringen. Ta även hänsyn till tidpunkt: peerinteraktioner synkroniseras inte alltid med aktuellt visuellt tillstånd, så tillståndet för kontrollen kan ändras mellan det att en peer skapas och metodkörning. För dessa scenarier kan leverantörer använda två dedikerade undantag:
- Kasta ElementNotAvailableException om du inte kan komma åt antingen ägaren till peer-elementet eller ett relaterat peer-element baserat på den ursprungliga informationen som ditt API fått. Du kan till exempel ha en peer som försöker köra dess metoder, men ägaren har sedan dess tagits bort från användargränssnittet, till exempel en modal dialogruta som har stängts. För en klient som inte .NET mappas den till UIA_E_ELEMENTNOTAVAILABLE.
- Kasta ElementNotEnabledException om det fortfarande finns en ägare, men ägaren befinner sig i ett läge som IsEnabled
=false som blockerar några av de specifika programmatiska ändringar som din kollega försöker utföra. För en klient som inte är .NET mappas den till UIA_E_ELEMENTNOTENABLED.
Mer allmänt, var konservativ med undantag. Många klienter kan inte konvertera providerundantag till meningsfulla användaråtgärder. I vissa sökvägar är no-op-beteende eller den lokala undantagshanteringen att föredra framför upprepade kast. Kom också ihåg att många UI Automation klienter är COM-baserade och främst utvärderar HRESULT resultat som S_OK.
Relaterade ämnen
Windows developer