【问题标题】:C# recursion to find automationElement in open dialog boxC#递归在打开的对话框中找到automationElement
【发布时间】:2016-03-07 14:56:03
【问题描述】:

单击下载按钮后,我正在尝试浏览文件。但我虽然编写了一个递归函数,可以使用 AutomationElement 库在任何窗口中查找控件,因此希望我可以在打开的对话框窗口中找到嵌套控件。这个功能现在不工作了。请让我知道问题出在哪里,或者如果您有任何建议,请告诉我。

问题是它永远不会到达 else 语句并且永远不会结束。所以我认为它根本找不到元素。

这是我试图使用的突出显示的元素:

screenshot from inspect

谢谢

 private AutomationElement GetElement(AutomationElement element, Condition conditions, string className)
    {
        AutomationElement boo = null;
        foreach (AutomationElement c in element.FindAll(TreeScope.Subtree, Automation.ControlViewCondition))
        {
            var child = c;
            if (c.Current.ClassName.Contains(className) == false)
            {
                GetElement(child, conditions, className);   
             }
            else
            {
                boo = child.FindFirst(TreeScope.Descendants, conditions);
            }
        }

        return boo;
    }

【问题讨论】:

  • 你没有提到它不起作用的方式。什么都没有发生?它会抛出异常吗?如果是,请提供异常信息。
  • 它永远不会到达 else 语句并且永远不会结束。所以我认为它根本找不到元素。谢谢
  • 好吧,不要忽略GetElement()的返回值。如果它不为空,它当然就是你要找的那个。

标签: c# recursion ui-automation automationelement


【解决方案1】:

树行者更适合这项任务。

使用示例:

// find a window
var window = GetFirstChild(AutomationElement.RootElement,
    (e) => e.Name == "Calculator");

// find a button
var button = GetFirstDescendant(window,
    (e) => e.ControlType == ControlType.Button && e.Name == "9");

// click the button
((InvokePattern)button.GetCurrentPattern(InvokePattern.Pattern)).Invoke();

使用委托递归查找后代元素的功能:

public static AutomationElement GetFirstDescendant(
    AutomationElement root, 
    Func<AutomationElement.AutomationElementInformation, bool> condition) {

    var walker = TreeWalker.ControlViewWalker;
    var element = walker.GetFirstChild(root);
    while (element != null) {
        if (condition(element.Current))
            return element;
        var subElement = GetFirstDescendant(element, condition);
        if (subElement != null)
            return subElement;
        element = walker.GetNextSibling(element);
    }
    return null;
}

使用委托查找子元素的功能:

public static AutomationElement GetFirstChild(
    AutomationElement root,
    Func<AutomationElement.AutomationElementInformation, bool> condition) {

    var walker = TreeWalker.ControlViewWalker;
    var element = walker.GetFirstChild(root);
    while (element != null) {
        if (condition(element.Current))
            return element;
        element = walker.GetNextSibling(element);
    }
    return null;
}

【讨论】:

  • 非常感谢您的回答。这是获取元素的好方法。但是,对我来说它仍然返回 null。控件是嵌入的,我不明白它为什么会找到它。我在我的原始帖子中添加了一个屏幕截图给你一个想法。
  • 您首先需要点击“Previous Location”以便创建“Address”控件。
  • 对不起,我不明白你的答案@florentbr。我应该先尝试获取“地址”组合框吗?谢谢,
  • 您得到一个空元素,因为在您调用该函数时,Windows 尚未创建控件。您从未提及您尝试与之交互的控件,所以我猜它是屏幕截图中的“地址”组合框。您需要更明确地说明您要在这里实现的目标,因为这篇文章的原始问题现已得到解答。
猜你喜欢
  • 2019-03-31
  • 1970-01-01
  • 2017-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-14
相关资源
最近更新 更多