Share via


WPF 自訂控制項的 UI 自動化

更新: 2008 年 7 月

Microsoft UI 自動化提供單一的通用介面,讓自動化用戶端可以用來檢查或操作各式各樣平台和架構的使用者介面。UI 自動化可以讓品質保證 (測試) 程式碼和協助工具應用程式 (例如螢幕助讀員),檢查使用者介面項目以及模擬其他程式碼與其間的使用者互動。如需跨所有平台的 UI 自動化的詳細資訊,請參閱網頁可及性

本主題描述如何對 WPF 應用程式中執行的自訂控制項,實作伺服器端 UI 自動化提供者。WPF 對 UI 自動化的支援,是透過與使用者介面項目樹狀目錄平行的對等自動化物件樹狀目錄而達成的。測試程式碼和提供協助工具功能的應用程式,可以直接使用自動化對等物件 (針對同處理序 (In-Process) 程式碼),或是透過 UI 自動化所提供的通用介面使用該物件。

這個主題包含下列章節。

  • 自動化對等類別
  • 內建的自動化對等類別
  • 衍生對等物件的安全性考量
  • 對等物件巡覽
  • 衍生對等物件中的自訂
  • 相關主題

自動化對等類別

WPF 控制項對 UI 自動化的支援,是透過衍生自 AutomationPeer 的對等類別樹狀目錄。依照慣例,對等類別名稱會以控制項類別名稱開頭,並以 "AutomationPeer" 結尾。例如,ButtonAutomationPeerButton 控制項類別的對等類別。對等類別大致相當於 UI 自動化控制項型別,但專屬於 WPF 項目。透過 UI 自動化介面存取 WPF 應用程式的自動化程式碼,並不會直接使用自動化對等物件,但相同處理序空間中的自動化程式碼則可以直接使用自動化對等物件。

內建的自動化對等類別

當項目接受來自使用者的介面活動時,或是當項目包含螢幕助讀員應用程式使用者所需要的資訊時,項目會實作自動化對等類別。並非所有的 WPF 視覺化項目都具有自動化對等物件。例如,ButtonTextBoxLabel 就是會實作自動化對等物件的類別範例。而不會實作自動化對等物件的類別範例,則有衍生自 Decorator 的類別 (例如 Border) 和以 Panel 為基礎的類別 (例如 GridCanvas)。

基底 Control 類別沒有對應的對等類別。如果您需要對等類別能夠對應到 Control 的衍生自訂控制項,則應該從 FrameworkElementAutomationPeer 衍生自訂對等類別。

衍生對等物件的安全性考量

自動化對等物件必須在部分信任的環境中執行。UIAutomationClient 組件中的程式碼並非設定成在部分信任環境下執行,因而自動化對等程式碼不應該參考該組件。您應該改為使用 UIAutomationTypes 組件中的類別。例如,您應該使用來自 UIAutomationTypes 組件的 AutomationElementIdentifiers 類別,這會對應到 UIAutomationClient 組件中的 AutomationElement 類別。在自動化對等程式碼中參考 UIAutomationTypes 組件是很安全的。

對等物件巡覽

找到自動化對等物件後,同處理序程式碼可以藉由呼叫物件的 GetChildrenGetParent 方法,巡覽對等物件樹狀目錄。在 GetChildrenCore 方法的對等物件實作中,有支援控制項內 WPF 項目間的巡覽。UI 自動化系統會呼叫這個方法,建置內含於控制項中的子項目的樹狀目錄 (例如,清單方塊中的清單項目)。預設的 UIElementAutomationPeer.GetChildrenCore 方法會周遊項目的視覺化樹狀目錄,以建置自動化對等物件的樹狀目錄。自訂控制項會覆寫這個方法,將子項目公開 (Expose) 給自動化用戶端,傳回用於傳遞資訊或允許使用者互動的項目自動化對等物件。

衍生對等物件中的自訂

所有衍生自 UIElementContentElement 的類別都包含保護的 (Protected) 虛擬方法 OnCreateAutomationPeer。WPF 會呼叫 OnCreateAutomationPeer 以取得每個控制項的自動化對等物件。自動化程式碼可以使用對等物件,取得控制項特性和功能的資訊,並模擬互動使用方式。支援自動化的自訂控制項必須覆寫 OnCreateAutomationPeer,並傳回衍生自 AutomationPeer 的類別執行個體。例如,如果自訂控制項衍生自 ButtonBase 類別,則 OnCreateAutomationPeer 傳回的物件應該衍生自 ButtonBaseAutomationPeer

實作自訂控制項時,必須覆寫基底自動化對等類別中用來描述您自訂控制項所專有的獨特行為的「核心」方法。

覆寫 OnCreateAutomationPeer

覆寫自訂控制項的 OnCreateAutomationPeer 方法,以便傳回您的提供者物件 (Provider Object),這些物件必須是直接或間接衍生自 AutomationPeer

覆寫 GetPattern

自動化對等物件可以簡化某些方面的伺服器端 UI 自動化提供者實作,但自訂控制項自動化對等物件必須仍能處理模式介面。就像非 WPF 提供者一樣,對等物件會提供 System.Windows.Automation.Provider 命名空間 (Namespace) 中介面的實作 (例如 IInvokeProvider),藉以支援控制項模式。控制項模式介面可經由對等物件本身或另一個物件而實作。而對等物件的 GetPattern 實作,則會傳回支援指定模式的物件。UI 自動化程式碼會呼叫 GetPattern 方法並指定 PatternInterface 列舉值。對 GetPattern 的覆寫應該會傳回實作指定模式的物件。如果控制項沒有模式的自訂實作,則可以呼叫 GetPattern 的基底型別 (Base Type) 實作,以擷取其實作,或者在這個控制項型別不支援該模式時擷取 null。例如,自訂 NumericUpDown 控制項可以設定為範圍內的值,所以其 UI 自動化對等物件會實作 IRangeValueProvider 介面。下列範例顯示如何因應 PatternInterface.RangeValue 值來覆寫對等物件的 GetPattern 方法。

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

GetPattern 方法也可以指定子項目做為模式提供者。下列程式碼顯示 ItemsControl 如何將捲動模式處理傳輸給其內部 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);
}

為了要指定模式處理的子項目,這段程式碼會取得子項目物件、藉由使用 CreatePeerForElement 方法建立對等物件、將新對等物件的 EventsSource 屬性設定為目前的對等物件,並傳回新的對等物件。對子項目設定 EventsSource 可以讓子項目不會出現在自動化對等物件樹狀目錄中,並可以將子項目引發的所有事件指示成源自於 EventsSource 中的指定控制項。ScrollViewer 控制項不會出現在自動化樹狀目錄中,且其產生的捲動事件源自於 ItemsControl 物件。

覆寫「核心」方法

自動化程式碼是經由呼叫對等類別的公用方法而取得控制項資訊的。若要提供您的控制項資訊,請在您的控制項實作與基底自動化對等類別所提供的實作不相同時,覆寫每個名稱以 "Core" 結尾的方法。而您的控制項至少必須實作 GetClassNameCoreGetAutomationControlTypeCore 方法,如下列範例所示。

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

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

您的 GetAutomationControlTypeCore 實作是以傳回 ControlType 值描述您的控制項。雖然還是可以傳回 ControlType.Custom,但如果要精確地描述您的控制項,您應該傳回一種更為專有的控制項型別。ControlType.Custom 的傳回值需要額外的工作,才能讓提供者實作 UI 自動化,而且 UI 自動化用戶端產品無法預測控制項結構、鍵盤互動和可能的控制項模式。

實作 IsContentElementCoreIsControlElementCore 方法,可以指出控制項是否包含資料內容或是否完成使用者介面中的互動角色 (或者是這兩項作業)。根據預設,這兩個方法都會傳回 true。這些設定可以改善螢幕助讀員這類自動化工具的可用性,自動化工具可以使用這些方法篩選自動化樹狀目錄。如果您的 GetPattern 方法會將模式處理傳輸給子項目對等物件,則子項目對等物件的 IsControlElementCore 方法可以傳回 false 以在自動化樹狀目錄中隱藏子項目對等物件。例如,ListBox 中的捲動作業是由 ScrollViewer 處理的,而 PatternInterface.Scroll 的自動化對等物件則是由與 ListBoxAutomationPeer 關聯的 ScrollViewerAutomationPeerGetPattern 方法傳回的。因此,ScrollViewerAutomationPeerIsControlElementCore 方法會傳回 false,所以 ScrollViewerAutomationPeer 不會出現在自動化樹狀目錄中。

自動化對等物件應該為您的控制項提供適當的預設值。請注意,參考您控制項的 XAML 可以藉由加入 AutomationProperties 屬性 (Attribute),覆寫您核心方法的對等實作。例如,下列 XAML 程式碼建立的按鈕會有兩個自訂的 UI 自動化屬性 (Property)。

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

實作模式提供者

自訂提供者所實作的介面,在主控項目是直接衍生自 Control 時會明確宣告。例如,下列程式碼即會為實作範圍值的 Control 宣告對等物件。

public class RangePeer1 : FrameworkElementAutomationPeer, IRangeValueProvider { }

如果主控控制項衍生自特定型別的控制項 (例如 RangeBase),則對等物件可以衍生自相當的衍生對等類別。在這種情況下,對等物件可衍生自 RangeBaseAutomationPeer,其會提供 IRangeValueProvider 的基底實作。下列程式碼顯示這類對等物件的宣告。

public class RangePeer2 : RangeBaseAutomationPeer { }

如需範例實作,請參閱 NumericUpDown 自訂控制項與佈景主題和 UI 自動化支援範例

引發事件

自動化用戶端可以訂閱自動化事件。自訂控制項必須藉由呼叫 RaiseAutomationEvent 方法,報告控制項狀態的變更。同樣地,當屬性值變更時,也要呼叫 RaisePropertyChangedEvent 方法。下列程式碼顯示如何從控制項程式碼內取得對等物件,以及如何呼叫方法來引發事件。基於最佳化因素,程式碼會判斷這個事件型別是否有任何接聽程式。只在有接聽程式時引發事件,可以避免不必要的額外負荷,並有助於維持控制項的回應性。

if (AutomationPeer.ListenerExists(AutomationEvents.PropertyChanged))
{
    NumericUpDownAutomationPeer peer = 
        UIElementAutomationPeer.FromElement(nudCtrl) as NumericUpDownAutomationPeer;

    if (peer != null)
    {
        peer.RaisePropertyChangedEvent(
            RangeValuePatternIdentifiers.ValueProperty,
            (double)oldValue,
            (double)newValue);
    }
}

請參閱

工作

NumericUpDown 自訂控制項與佈景主題和 UI 自動化支援範例

測試指令碼產生器範例

概念

UI 自動化概觀

伺服器端 UI 自動化提供者實作

變更記錄

日期

記錄

原因

2008 年 7 月

加入主題。

資訊加強。