1

シーンの設定

猫のグループと犬のグループを含む (データ駆動型) GroupBox で構成される単純な Microsoft WPF アプリケーションがあります。Cat グループと Dog グループの両方に、それぞれ 2 つのグループ アイテムが含まれています。アプリケーションを実行すると、すべて正常に表示され、グループとそのコンテンツが画面に表示されます。

アプリケーションを実行すると、次のウィンドウが生成されます。

アプリケーション出力

ただし、UIAutomation テストを作成すると、グループ項目の AutomationElements が見つかりません。グループだけです。AutomationElement ルートを使用してアクセスするか、以下の画像のように UISpy.exe で表示されるのは、のグループのみです。

UISpy はグループの子を表示しません

個々の Cat および Dog グループ項目の子コンポーネントが存在しないため、テスト コードで AutomationElements として取得できるようにする必要があります。

    [TestMethod]
    public void MyTest()
    {
        Condition controlTypeCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Group);
        var foreGroundWindow = GetForegroundWindow();
        var collection = foreGroundWindow.FindAll(TreeScope.Descendants, controlTypeCondition);
        foreach (AutomationElement element in collection)
        {
            logger.Debug("Name: " + element.Current.Name);
            var children = element.FindAll(TreeScope.Children, Condition.TrueCondition);
            logger.Debug("Number of children: " + children.Count);
        }
    }

上記は現在出力します:

名前: 猫

子供の数: 0

名前: 犬

子供の数: 0

問題の再現

この問題を再現するには、Visual Studio で新しい WPF アプリケーション (WpfApplication1 という名前) を作成し、MainWindow.xaml の内容を次のものに置き換えます。

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
        </ResourceDictionary.MergedDictionaries>
        <XmlDataProvider x:Key="data">
            <x:XData>
                <Animals xmlns="">
                    <Animal name="Felix" Species="Cat" />
                    <Animal name="Garfield" Species="Cat" />
                    <Animal name="Rex" Species="Dog" />
                    <Animal name="Rover" Species="Dog" />
                </Animals>
            </x:XData>
       </XmlDataProvider>
        <CollectionViewSource x:Key="AnimalsBySpecies" Source="{Binding Source={StaticResource data}, XPath=Animals/Animal}">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="@Species" />
            </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </ResourceDictionary>
</Window.Resources>

<ItemsControl ItemsSource="{Binding Source={StaticResource AnimalsBySpecies}}">
    <ItemsControl.GroupStyle>
        <GroupStyle>
            <GroupStyle.ContainerStyle>
                <Style TargetType="{x:Type GroupItem}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type GroupItem}">
                                <GroupBox Header="{Binding Name}">
                                    <ItemsPresenter />
                                </GroupBox>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </GroupStyle.ContainerStyle>
        </GroupStyle>
    </ItemsControl.GroupStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding XPath=@name}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
</Window>

実際には、MVVM アプリケーションであるため、私のコードはこのようには見えません。ただし、簡潔にするために、同じ問題を再現する単一の XAML ファイルに簡略化しました。注意すべき重要な点は、グループのコンテンツが XAML バインディングから設定されることです。

では、UIAutomation を使用してコンテンツにアクセスするにはどうすればよいでしょうか?

どんな助けでも大歓迎です!

4

3 に答える 3

0

UISpy は、WPF のウィンドウや要素を検査するのに適したツールではありません。Snoopを使用することをお勧めします。

ただし、この質問は似ているようで、そこに示されている解決策で問題が解決する場合があります。

于 2013-07-12T07:40:47.233 に答える
0

This is a well-known issue where TextBlock's that are inside data templates are not visible in the Control or Content views of the automation tree. This is an optimization made by WPF. There are three possible resolutions.

One is to use .NET 4.5 where, I believe, this was changed so that TextBlock's will now be included.

Another is to make sure you use the Raw view. This is easy in UI Spy (go to View > Raw View) however it somewhat cumbersome in automated tests as you cannot use normal FindFirst or FindAll conditions. You have to use TreeWalker.RawViewWalker to manually inspect the automation tree.

Finally, you can subclass the TextBlock control and override the OnCreateAutomationPeer method to return a custom AutomationPeer implementation with IsControlElement returning true. This outlined in this answer.

于 2013-08-28T14:13:39.637 に答える