c# System.Windows.Automation获取元素文本

本文关键字:元素 文本 获取 Automation System Windows | 更新日期: 2023-09-27 18:04:52

我正在尝试从c#中的自动化应用程序控件中获取文本/标签。

到目前为止,我能够通过这个函数获得应用程序(例如记事本)的AutomationElement树:

    private void WalkControlElements(AutomationElement rootElement, TreeNode treeNode)
    {
        AutomationElement elementNode = TreeWalker.ContentViewWalker.GetFirstChild(rootElement);;
        while (elementNode != null)
        {
            TreeNode childTreeNode = treeNode.Nodes.Add(elementNode.Current.ControlType.LocalizedControlType);
            // here I want to get text from 'elementNode'
            WalkControlElements(elementNode, childTreeNode);
            elementNode = TreeWalker.ControlViewWalker.GetNextSibling(elementNode);
        }
    }

我试图遵循这篇文章http://msdn.microsoft.com/en-us/library/ms788751(v=vs.110).aspx,但它只能获得文本属性,如字体名称,字体粗细等。

有没有人能告诉我正确的程序如何获得与自动化元素文本?

c# System.Windows.Automation获取元素文本

该示例向您展示了如何获取文本属性,即关于在UI中显示文本的信息,而不是实际显示的文本。为一般应用程序获取所有实际显示的文本比它最初出现时要困难得多。

由于有几种获取文本的方法,并且应用程序和控件的支持不一致,这使得它变得困难。有两种模式有一定的用途,ValuePatternTextPattern。按照惯例,Name属性包含显示给用户的文本,但遵守这一点并不一致。下面是我在UI自动化测试中使用的辅助方法。它基本上通过这些模式检查控件是否支持,然后返回到Name。

public static class AutomationExtensions
{
    public static string GetText(this AutomationElement element)
    {
        object patternObj;
        if (element.TryGetCurrentPattern(ValuePattern.Pattern, out patternObj))
        {
            var valuePattern = (ValuePattern)patternObj;
            return valuePattern.Current.Value;
        }
        else if (element.TryGetCurrentPattern(TextPattern.Pattern, out patternObj))
        {
            var textPattern = (TextPattern)patternObj;
            return textPattern.DocumentRange.GetText(-1).TrimEnd(''r'); // often there is an extra ''r' hanging off the end.
        }
        else
        {
            return element.Current.Name;
        }
    }
}

它负责从简单的控件中获取文本,如标签、文本框(包括vanilla textbox和richtextbox)和按钮。像列表框和组合框这样的控件(特别是在WPF中)可能更狡猾,因为它们的项可以被虚拟化,所以在用户与它们交互之前,它们可能不存在于自动化树中。您可能想要过滤并仅在某些UI Automation控件类型(如Edit, Text和Document)上调用此方法,这些控件类型包含文本。

Mike Zboray的回答很好。如果您可以访问模式匹配,下面是相同的(压缩)代码:

public static class AutomationExtensions
{
    public static string GetText(this AutomationElement element)
    => element.TryGetCurrentPattern(ValuePattern.Pattern, out object patternValue) ? ((ValuePattern)patternValue).Current.Value
        : element.TryGetCurrentPattern(TextPattern.Pattern, out object patternText) ? ((TextPattern)patternText).DocumentRange.GetText(-1).TrimEnd(''r') // often there is an extra ''r' hanging off the end.
        : element.Current.Name;
}