バージョン

UI オートメーションのサポート

Ultimate UI for WPF コントロール スイートは Microsoft® UI Automation を完全にサポートします。UI Automation フレームワークによって、アプリケーションの UI 要素にアクセスしたり障害を持つエンドユーザーにこの情報を提供するためのスクリーンリーダーなどの支援技術が可能となります。

UI Automation のもうひとつの主な用途は自動化テストです。フレームワークによってテスト スクリプトは UI 要素にアクセスして操作することができます。

UI Automation の詳細については、この Microsoft ウェブサイトを参照してください。

Ultimate UI for WPF UI コントロールは以下の方法で UI Automation をサポートします。

  • 各コントロールには、AutomationPeer クラスから派生するピア クラスがあります。

以下のコードは xamRadialGauge コントロールの GaugeAutomationPeer を示します。

Visual Basic の場合:

Public Class GaugeAutomationPeer
    Inherits FrameworkElementAutomationPeer

C# の場合:

public class GaugeAutomationPeer : FrameworkElementAutomationPeer
  • コントロールのピア クラスそれぞれは Core メソッドをオーバーライドして適切な UI 自動化パターンを実装します。コントロール パターン の詳細については、この Microsoft ウェブサイトを参照してください。

  • それぞれの Ultimate UI for WPF UI コントロールは OnCreateAutomationPeer メソッドをオーバーライドします。以下の例は xamRadialGauge コントロールを示します。

Visual Basic の場合:

Protected Overrides Function OnCreateAutomationPeer() As AutomationPeer
    Return New GaugeAutomationPeer(Me)
End Function

C# の場合:

protected override AutomationPeer OnCreateAutomationPeer()
{
   return new GaugeAutomationPeer(this);
}
  • 自動化クライアントは変更状態またはプロパティを通知する自動化イベントを発生させます。UI Automation Events の詳細については、この Microsoft ウェブサイトを参照してください。以下のコードは、xamRadialGauge の Needle の値が変更される時に発生するイベントのイベント ハンドラーを示します。

ピア クラスで

Visual Basic の場合:

Public Sub New(needle As RadialGaugeNeedle)
    MyBase.New(needle)
    Me.Needle = needle
    Me.Needle.ValueChanged += New EventHandler(Of ValueChangedEventArgs)(AddressOf Needle_ValueChanged)
End Sub
Private Sub Needle_ValueChanged(sender As Object, e As ValueChangedEventArgs)
    Me.RaiseValueChangedEvent(e.NewValue)
End Sub
Private Sub RaiseValueChangedEvent(newValue As Double)
    If ListenerExists(AutomationEvents.PropertyChanged) Then
        Me.RaisePropertyChangedEvent(RangeValuePatternIdentifiers.ValueProperty, 0.0, newValue)
    End If
End Sub

C# の場合:

public RadialGaugeNeedleAutomationPeer(RadialGaugeNeedle needle)
:
    base(needle)
{
    this.Needle = needle;
    this.Needle.ValueChanged +=
        new EventHandler<ValueChangedEventArgs>(Needle_ValueChanged);
}
private void Needle_ValueChanged(object sender, ValueChangedEventArgs e)
{
    this.RaiseValueChangedEvent(e.NewValue);
}
private void RaiseValueChangedEvent(double newValue)
{
    if (ListenerExists(AutomationEvents.PropertyChanged))
    {
        this.RaisePropertyChangedEvent
          (RangeValuePatternIdentifiers.ValueProperty, 0.0, newValue);
    }
}

クライアント アプリケーションで

Visual Basic の場合:

' PropertyChanged イベントの EventHandler の新しいインスタンスを作成します
Dim valueEvent As New AutomationPropertyChangedEventHandler(AddressOf SampleEventHandler)
' Value プロパティの PropertyChanged イベントの EventHandler を追加します
Automation.AddAutomationPropertyChangedEventHandler(needleElement, TreeScope.Subtree, valueEvent, RangeValuePattern.ValueProperty)
' EventHandler
Private Sub SampleEventHandler(sender As Object, e As AutomationPropertyChangedEventArgs)
    If e.[Property] = RangeValuePattern.ValueProperty Then
        MessageBox.Show([String].Format("New value = {0}", e.NewValue))
    End If
End Sub

C# の場合:

// PropertyChanged イベントの EventHandler の新しいインスタンスを作成します
AutomationPropertyChangedEventHandler valueEvent =
    new AutomationPropertyChangedEventHandler(SampleEventHandler);
// Value プロパティの PropertyChanged イベントの EventHandler を追加します
Automation.AddAutomationPropertyChangedEventHandler
    (needleElement, TreeScope.Subtree, valueEvent, RangeValuePattern.ValueProperty);
// EventHandler
private void SampleEventHandler(object sender, AutomationPropertyChangedEventArgs e)
{
    if (e.Property == RangeValuePattern.ValueProperty)
    {
        MessageBox.Show(String.Format("New value = {0}", e.NewValue));
    }
}
  • UISpy (詳細は、この ウェブサイトを参照) などのアプリケーションとカスタムの自動化クライアントは WPF アプリケーションで Infragistics コンポーネントにアクセスできます。

以下の API リンクをクリックして、各コントロールの自動化ピア クラスを確認します。

以下の例は、カスタム自動化クライアントを使用して、自動化クライアントが Ultimate UI for WPF コンポーネントにアクセスできる方法を示します。

以下は xamRadialGauge を含むシンプルな WPF アプリケーションです。

XAML の場合:

<UserControl x:Class="UIAutomationSample.MainPage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:ig="http://schemas.infragistics.com/xaml">
    <Grid x:Name="LayoutRoot">
        <ig:XamRadialGauge>
            <ig:XamRadialGauge.Scales>
                <ig:RadialGaugeScale StartValue="0"
                                     EndValue="100"
                                     Interval="10"
                                     StartAngle="135"
                                     EndAngle="405">
                    <ig:RadialGaugeScale.LabelGroups>
                        <ig:RadialGaugeLabelGroup />
                    </ig:RadialGaugeScale.LabelGroups>
                    <ig:RadialGaugeScale.Needles>
                        <ig:RadialGaugeNeedle Value="50" AutomationProperties.AutomationId="RadialNeedle" />
                    </ig:RadialGaugeScale.Needles>
                </ig:RadialGaugeScale>
            </ig:XamRadialGauge.Scales>
        </ig:XamRadialGauge>
    </Grid>
</UserControl>

WPF 自動化クライアント:

XAML の場合:

<Window x:Class="WpfAutomationClient.Window"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Automation Clien Window"
        Height="300"
        Width="300">
    <StackPanel>
        <TextBlock Text="Automation ID:" FontWeight="Bold" />
        <TextBox x:Name="txtAutomationId" Text="RadialNeedle" />
        <Button x:Name="btnAutomate" Click="btnAutomate_Click"
                Content="Connect" Margin="0,15,0,0" />
        <TextBlock Text="Status:" FontWeight="Bold"
                   Margin="0,15,0,0" />
        <TextBlock x:Name="lblStatus" Text="Disconnected" />
    </StackPanel>
</Window>

イベント ハンドラーの実装は指定された AutomationId で Radial Gauge Needle インスタンスを求めてサンプルの WPF アプリケーションを検索します。検出されたら、値を 20 に設定します。

Visual Basic の場合:

Private Sub btnAutomate_Click(sender As Object, e As RoutedEventArgs)
    Dim process__1 As Process = Process.GetProcessesByName("iexplore").FirstOrDefault()
    If process__1 Is Nothing Then
        lblStatus.Text = "Interned Explorer is not running."
        Return
    End If
    Dim browserInstance As AutomationElement = AutomationElement.FromHandle(process__1.MainWindowHandle)
    Dim automationId As [String] = txtAutomationId.Text.Trim()
    Dim treeWalker As New TreeWalker(New PropertyCondition(AutomationElement.AutomationIdProperty, automationId))
    Dim needleElement As AutomationElement = treeWalker.GetFirstChild(browserInstance)
    If needleElement Is Nothing Then
        lblStatus.Text = "Can't find a Radial Gauge Needle."
        Return
    End If
    Dim pattern As RangeValuePattern = TryCast(needleElement.GetCurrentPattern(RangeValuePattern.Pattern), RangeValuePattern)
    If pattern Is Nothing Then
        lblStatus.Text = "RangeValuePattern is not implemented."
        Return
    End If
    pattern.SetValue(20)
    lblStatus.Text = "Radial Gauge Needle Changed."
End Sub

C# の場合:

private void btnAutomate_Click(object sender, RoutedEventArgs e)
{
    Process process = Process.GetProcessesByName("iexplore").FirstOrDefault();
    if (process == null)
    {
        lblStatus.Text = "Interned Explorer is not running.";
        return;
    }
    AutomationElement browserInstance =
        AutomationElement.FromHandle(process.MainWindowHandle);
    String automationId = txtAutomationId.Text.Trim();
    TreeWalker treeWalker = new TreeWalker(
        new PropertyCondition
         (AutomationElement.AutomationIdProperty, automationId));
    AutomationElement needleElement = treeWalker.GetFirstChild(browserInstance);
    if (needleElement == null)
    {
        lblStatus.Text = "Can't find a Radial Gauge Needle.";
        return;
    }
    RangeValuePattern pattern = needleElement.GetCurrentPattern
        (RangeValuePattern.Pattern) as RangeValuePattern;
    if (pattern == null)
    {
        lblStatus.Text = "RangeValuePattern is not implemented.";
        return;
    }
    pattern.SetValue(20);
    lblStatus.Text = "Radial Gauge Needle Changed.";
}

以下の例は、WebAii for ASP.Net に基づいた、Infragistics ユニット テスト フレームワークによってテスト自動化ピアクラスを使用する方法を示します。

Visual Basic の場合:

<TestMethod> _
<Description("Validates the existance of a Radial Gauge Needle's RangeValuePattern.")> _
Public Sub Validate_RadialNeedle_RangeValuePattern()
    ' ラジアル ゲージを作成します
    Dim myRadialGauge As XamRadialGauge = LoadRadialGaugeProperties()
    ' ラジアル ゲージの針を取得します
    Dim needle As RadialGaugeNeedle = myRadialGauge.Scales(0).Needles(0)
    Me.UIThread.[Do](Function()
        Dim peer As RadialGaugeNeedleAutomationPeer = DirectCast(RadialGaugeNeedleAutomationPeer.CreatePeerForElement(needle), RadialGaugeNeedleAutomationPeer)
        Dim rangeValueProvider As IRangeValueProvider = DirectCast(peer.GetPattern(PatternInterface.RangeValue), IRangeValueProvider)
        Assert.IsNotNull(rangeValueProvider)
    End Function)
    Thread.Sleep(1000)
End Sub

C# の場合:

[TestMethod]
[Description("Validates the existance of a Radial Gauge Needle's RangeValuePattern.")]
public void Validate_RadialNeedle_RangeValuePattern()
{
    // ラジアル ゲージを作成します
    XamRadialGauge myRadialGauge = LoadRadialGaugeProperties();
    // ラジアル ゲージの針を取得します
    RadialGaugeNeedle needle = myRadialGauge.Scales[0].Needles[0];
    this.UIThread.Do(() =>
    {
        RadialGaugeNeedleAutomationPeer peer =  (RadialGaugeNeedleAutomationPeer)RadialGaugeNeedleAutomationPeer.CreatePeerForElement
(needle);
        IRangeValueProvider rangeValueProvider = (IRangeValueProvider)peer.GetPattern(PatternInterface.RangeValue);
        Assert.IsNotNull(rangeValueProvider);
    });
    Thread.Sleep(1000);
}