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

时间:2014-05-24 22:17:13

标签: c# ui-automation

我正在尝试使用C#中的Automation实现应用程序控件的文本/标签。

到目前为止,我可以使用此函数获取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进行操作,但它只能将文本属性作为字体名称,字体粗细等等。

有人能指出正确的程序如何使用Automation获取元素文本吗?

2 个答案:

答案 0 :(得分:9)

该示例向您展示了如何获取文本属性,即有关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文本框和richtextbox)以及按钮。像列表框和组合框(尤其是WPF)这样的控件可以很简单,因为它们的项可以虚拟化,因此在用户与它们交互之前它们可能不存在于自动化树中。您可能希望仅在某些UI自动化控件类型(如您知道包含文本的编辑,文本和文档)上过滤和调用此方法。

答案 1 :(得分:0)

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

InletCurrent