WPF Özel Denetiminin UI Otomasyonu

UI Otomasyonu, otomasyon istemcilerinin çeşitli platformların ve çerçevelerin kullanıcı arabirimlerini incelemek veya çalıştırmak için kullanabileceği tek, genelleştirilmiş bir arabirim sağlar. UI Otomasyonu hem kalite güvencesi (test) koduna hem de ekran okuyucular gibi erişilebilirlik uygulamalarının kullanıcı arabirimi öğelerini incelemesine ve diğer kodlardan kullanıcı etkileşimi simülasyonu yapmalarına olanak tanır. Tüm platformlarda UI Otomasyonu hakkında bilgi için bkz. Erişilebilirlik.

Bu konuda, WPF uygulamasında çalışan özel bir denetim için sunucu tarafı UI Otomasyonu sağlayıcısının nasıl uygulandığı açıklanmaktadır. WPF, kullanıcı arabirimi öğelerinin ağacını paralel hale getiren eş otomasyon nesneleri ağacı üzerinden UI Otomasyonu destekler. Test kodu ve erişilebilirlik özellikleri sağlayan uygulamalar, otomasyon eş nesnelerini doğrudan (işlem içi kod için) veya UI Otomasyonu tarafından sağlanan genelleştirilmiş arabirim aracılığıyla kullanabilir.

Otomasyon Eş Sınıfları

WPF denetimleri, 'den AutomationPeertüretilen eş sınıflardan oluşan bir ağaç aracılığıyla UI Otomasyonu destekler. Kural gereği, eş sınıf adları denetim sınıfı adıyla başlar ve "AutomationPeer" ile biter. Örneğin, ButtonAutomationPeer denetim sınıfının Button eş sınıfıdır. Eş sınıfları kabaca UI Otomasyonu denetim türlerine eşdeğerdir, ancak WPF öğelerine özeldir. UI Otomasyonu arabirimi aracılığıyla WPF uygulamalarına erişen otomasyon kodu doğrudan otomasyon eşlerini kullanmaz, ancak aynı işlem alanında otomasyon kodu otomasyon eşlerini doğrudan kullanabilir.

Yerleşik Otomasyon Eş Sınıfları

Öğeler, kullanıcıdan arabirim etkinliğini kabul ederse veya ekran okuyucu uygulamalarının kullanıcıları tarafından gereken bilgileri içeriyorsa bir otomasyon eş sınıfı uygular. Tüm WPF görsel öğelerinin otomasyon eşleri yoktur. Otomasyon eşlerini uygulayan sınıflara örnek olarak Button, TextBoxve Labelverilebilir. Otomasyon eşleri uygulamayan sınıflara örnek olarak , gibi türetilen Decoratorsınıflar ve ve gibi GridCanvasöğesini Paneltemel alan sınıflar verilebilir.Border

Temel Control sınıfın karşılık gelen bir eş sınıfı yok. 'den Controltüretilen özel bir denetime karşılık gelen bir eş sınıfına ihtiyacınız varsa, özel eş sınıfını öğesinden FrameworkElementAutomationPeertüretmelisiniz.

Türetilmiş Eşler için GüvenlikLe İlgili Dikkat Edilmesi Gerekenler

Otomasyon eşleri kısmi güven ortamında çalıştırılmalıdır. UIAutomationClient derlemesindeki kod, kısmi güven ortamında çalışacak şekilde yapılandırılmadı ve otomasyon eş kodu bu derlemeye başvurmamalıdır. Bunun yerine, UIAutomationTypes derlemesindeki sınıfları kullanmanız gerekir. Örneğin, UIAutomationClient derlemesindeki sınıfa AutomationElement karşılık gelen UIAutomationTypes derlemesindeki sınıfını kullanmanız AutomationElementIdentifiers gerekir. Otomasyon eş kodunda UIAutomationTypes derlemesine başvurmak güvenlidir.

Eş Gezintisi

Otomasyon eşleri bulunduktan sonra işlem içi kod, nesnenin GetChildren ve GetParent yöntemlerini çağırarak eş ağaçta gezinebilir. Bir denetim içindeki WPF öğeleri arasında gezinme, eşlerin yöntemini uygulaması GetChildrenCore tarafından desteklenir. UI Otomasyonu sistemi, bir denetimin içinde yer alan alt öğelerden oluşan bir ağaç oluşturmak için bu yöntemi çağırır; örneğin, liste kutusundaki liste öğeleri. Varsayılan UIElementAutomationPeer.GetChildrenCore yöntem, otomasyon eşlerinin ağacını oluşturmak için öğelerin görsel ağacından geçiş yapar. Özel denetimler, bilgileri aktaran veya kullanıcı etkileşimine izin veren öğelerin otomasyon eşlerini döndürerek alt öğeleri otomasyon istemcilerine göstermek için bu yöntemi geçersiz kılar.

Türetilmiş Eşteki Özelleştirmeler

'den UIElement türetilen ve ContentElement korumalı sanal yöntemini OnCreateAutomationPeeriçeren tüm sınıflar. Her denetim için otomasyon eş nesnesini almak için WPF çağrıları OnCreateAutomationPeer . Otomasyon kodu, bir denetimin özellikleri ve özellikleri hakkında bilgi almak ve etkileşimli kullanımın benzetimini yapmak için eş kullanabilir. Otomasyonu destekleyen özel bir denetim, öğesinden AutomationPeertüretilen bir sınıfın örneğini geçersiz kılmalı OnCreateAutomationPeer ve döndürmelidir. Örneğin, özel bir denetim sınıfından ButtonBase türetilirse, tarafından OnCreateAutomationPeer döndürülen nesne öğesinden ButtonBaseAutomationPeertüretilmelidir.

Özel denetim uygularken, temel otomasyon eş sınıfından benzersiz ve özel denetiminize özgü davranışı açıklayan "Core" yöntemlerini geçersiz kılmanız gerekir.

OnCreateAutomationPeer'ı Geçersiz Kıl

OnCreateAutomationPeer Doğrudan veya dolaylı olarak öğesinden AutomationPeertüretmesi gereken sağlayıcı nesnenizi döndürmesi için özel denetiminizin yöntemini geçersiz kılın.

GetPattern'ı Geçersiz Kıl

Otomasyon eşleri, sunucu tarafı UI Otomasyonu sağlayıcılarının bazı uygulama yönlerini basitleştirir, ancak özel denetim otomasyon eşlerinin yine de desen arabirimlerini işlemesi gerekir. WPF olmayan sağlayıcılar gibi eşler de ad alanında System.Windows.Automation.Provider gibi IInvokeProviderarabirimlerin uygulamalarını sağlayarak denetim desenlerini destekler. Denetim deseni arabirimleri eş tarafından veya başka bir nesne tarafından uygulanabilir. Eş'in uygulaması GetPattern , belirtilen deseni destekleyen nesneyi döndürür. UI Otomasyonu kodu yöntemini çağırır GetPattern ve bir PatternInterface numaralandırma değeri belirtir. geçersiz kılmanız GetPattern , belirtilen deseni uygulayan nesneyi döndürmelidir. Denetiminiz özel bir desen uygulamasına sahip değilse, temel türün uygulamasını GetPattern çağırarak bu denetim türü için desen desteklenmiyorsa uygulamasını veya null değerini alabilirsiniz. Örneğin, özel bir NumericUpDown denetimi bir aralık içindeki bir değere ayarlanabilir, bu nedenle UI Otomasyonu eş arabirimi uygularIRangeValueProvider. Aşağıdaki örnekte, eş yönteminin GetPattern bir PatternInterface.RangeValue değere yanıt vermek için nasıl geçersiz kılınmış olduğu gösterilmektedir.

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

Bir GetPattern yöntem, desen sağlayıcısı olarak bir alt öğe de belirtebilir. Aşağıdaki kod, kaydırma deseni işlemesini kendi iç ScrollViewer denetiminin eşine nasıl ItemsControl aktaracaklarını gösterir.

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  

Desen işleme için bir alt öğe belirtmek için, bu kod alt öğe nesnesini alır, yöntemini kullanarak CreatePeerForElement bir eş oluşturur, yeni eş özelliğini geçerli eşe ayarlar EventsSource ve yeni eş döndürür. Bir alt öğedeki ayar EventsSource , alt öğesinin otomasyon eş ağacında görünmesini engeller ve alt öğe tarafından tetiklenen tüm olayları içinde EventsSourcebelirtilen denetimden kaynaklanır olarak belirler. Denetim ScrollViewer otomasyon ağacında görünmez ve oluşturduğu kaydırma olayları nesneden ItemsControl geliyor gibi görünür.

"Core" Yöntemlerini Geçersiz Kılma

Otomasyon kodu, eş sınıfının genel yöntemlerini çağırarak denetiminiz hakkında bilgi alır. Denetiminiz hakkında bilgi sağlamak için, denetim uygulamanız temel otomasyon eş sınıfı tarafından sağlanandan farklı olduğunda adı "Core" ile biten her yöntemi geçersiz kılın. Aşağıdaki örnekte gösterildiği gibi, denetiminizin en azından ve GetAutomationControlTypeCore yöntemlerini uygulaması GetClassNameCore gerekir.

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

uygulamanız GetAutomationControlTypeCore , bir ControlType değer döndürerek denetiminizi açıklar. döndürebilmenize ControlType.Customrağmen, denetiminizi doğru şekilde açıklıyorsa daha belirli denetim türlerinden birini döndürmelisiniz. dönüş değeriControlType.Custom, sağlayıcının UI Otomasyonu uygulaması için ek çalışma gerektirir ve UI Otomasyonu istemci ürünleri denetim yapısını, klavye etkileşimini ve olası denetim desenlerini tahmin edemez.

IsContentElementCore Denetiminizin veri içeriği içerip içermediğini veya kullanıcı arabiriminde (veya her ikisinde) etkileşimli bir rolü yerine getirip getirmediğini belirtmek için ve IsControlElementCore yöntemlerini uygulayın. Varsayılan olarak, her iki yöntem de döndürür true. Bu ayarlar, otomasyon ağacını filtrelemek için bu yöntemleri kullanabilen ekran okuyucular gibi otomasyon araçlarının kullanılabilirliğini artırır. Yönteminiz GetPattern desen işlemeyi bir alt öğe eşine aktarırsa, alt öğe eş öğesinin IsControlElementCore yöntemi, alt öğe eşlerini otomasyon ağacından gizlemek için false döndürebilir. Örneğin, içinde ListBox kaydırma bir ScrollViewertarafından işlenir ve otomasyon PatternInterface.Scroll eş ile ilişkili ListBoxAutomationPeeryöntemi ScrollViewerAutomationPeer tarafından GetPattern döndürülür. Bu nedenle, IsControlElementCore yöntemi, otomasyon ağacında görünmemesi için döndürürfalseScrollViewerAutomationPeer.ScrollViewerAutomationPeer

Otomasyon eşinizin denetiminiz için uygun varsayılan değerleri sağlaması gerekir. Denetiminize başvuran XAML'nin öznitelikleri ekleyerek AutomationProperties çekirdek yöntemlerin eş uygulamalarınızı geçersiz kılabileceğini unutmayın. Örneğin, aşağıdaki XAML iki özelleştirilmiş UI Otomasyonu özelliği olan bir düğme oluşturur.

<Button AutomationProperties.Name="Special"
    AutomationProperties.HelpText="This is a special button."/>  

Desen Sağlayıcılarını Uygulama

Özel bir sağlayıcı tarafından uygulanan arabirimler, sahip olan öğe doğrudan öğesinden Controltüretilirse açıkça bildirilir. Örneğin, aşağıdaki kod bir aralık değeri uygulayan için bir Control eş bildirir.

public class RangePeer1 : FrameworkElementAutomationPeer, IRangeValueProvider { }  
Public Class RangePeer1  
    Inherits FrameworkElementAutomationPeer  
    Implements IRangeValueProvider  
End Class  

Sahip olan denetim gibi RangeBasebelirli bir denetim türünden türetilirse eş eşdeğer türetilmiş eş sınıfından türetilebilir. Bu durumda eş, temel uygulamasını IRangeValueProvidersağlayan 'den RangeBaseAutomationPeertüretilir. Aşağıdaki kod, böyle bir eş bildirimini gösterir.

public class RangePeer2 : RangeBaseAutomationPeer { }  
Public Class RangePeer2  
    Inherits RangeBaseAutomationPeer  
End Class  

Örnek bir uygulama için, NumericUpDown özel denetimini uygulayan ve kullanan C# veya Visual Basic kaynak koduna bakın.

Olayları Tetikle

Otomasyon istemcileri otomasyon olaylarına abone olabilir. Özel denetimlerin, yöntemini çağırarak denetim durumundaki değişiklikleri bildirmesi RaiseAutomationEvent gerekir. Benzer şekilde, bir özellik değeri değiştiğinde yöntemini çağırın RaisePropertyChangedEvent . Aşağıdaki kod, denetim kodunun içinden eş nesnesinin nasıl alınıp bir olay oluşturmak için bir yöntem çağırmayı gösterir. İyileştirme olarak kod, bu olay türü için dinleyici olup olmadığını belirler. Olayın yalnızca dinleyiciler olduğunda yükseltilmesi gereksiz ek yükü önler ve denetimin yanıt vermeye devam etmesine yardımcı olur.

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

Ayrıca bkz.