c# - Microsoft UIAutomation 无法检索 WPF GroupBox 中的子组件

标签 c# wpf microsoft-ui-automation

设置场景

我有一个简单的 Microsoft WPF 应用程序,它由一个(数据驱动的)GroupBox 组成,其中包含一组猫和一组狗。猫组和狗组各包含两个组项目。当我运行应用程序时,一切都显示正常,我可以在屏幕上看到组及其内容。

运行应用程序会生成以下窗口:

Application Output

但是,当我创建 UIAutomation 测试时,我找不到组项的任何 AutomationElements,只能找到组;只有 CatDog 组可以使用 AutomationElement 路由访问,或者在 UISpy.exe 中看到,如下图所示:

UISpy show no children for the groups

单个猫和狗组项目的子组件不存在,我需要能够在我的测试代码中将它们作为 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);
        }
    }

以上当前输出:

名称:猫

child 数量:0

名称:狗

child 数量: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 绑定(bind)填充的。

那么如何使用 UIAutomation 获取内容?

非常感谢任何帮助!

最佳答案

这是一个众所周知的问题,其中TextBlock数据模板内的 '在 Control 中不可见或Content自动化树的 View 。这是WPF所做的优化。存在三种可能的解决方案。

一种是使用 .NET 4.5,我相信,它已更改,以便 TextBlock现在将被包括在内。

另一个是确保您使用 Raw看法。这在 UI Spy 中很容易(转到“ View ”>“原始 View ”),但在自动化测试中有点麻烦,因为您无法使用正常的 FindFirstFindAll状况。您必须使用TreeWalker.RawViewWalker手动检查自动化树。

最后,您可以对 TextBlock 进行子类化控制和覆盖 OnCreateAutomationPeer返回自定义的方法 AutomationPeer实现 IsControlElement返回真。这在answer中概述了.

关于c# - Microsoft UIAutomation 无法检索 WPF GroupBox 中的子组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17596855/

相关文章:

c# - WCF WebHttp 服务中的错误处理,仅带有 WebFaultException xml 格式的异常

.net - "Items collection must be empty before using ItemsSource."

c++ - rootElement->FindFirst(...) 无法找到 Inspect 看到的元素

c# - 使用 UIAutomation 获取按钮的路径

c# - 定义环境变量

c# - 在 ASP.NET 页面加载时运行 JavaScript 代码

c# - 使用 javascript 从代码隐藏获取 DataTable 值到客户端

wpf - 什么是WPF浏览器应用类型项目?

c# - 从一组控制台应用程序中干净地杀死一个控制台应用程序

c++ - 如何通过将光标悬停在UIAutomationElement的NamePropertyId上?