繁体   English   中英

无法使用UIAutomation定位元素

[英]Unable to locate element using UIAutomation

我将Microsoft的UIAutomation库用于C#。 我有一个具有以下属性的元素:

  • LocalizedControlType:“编辑”
  • AutomationId:“数据库”
  • 只读:错误
  • 文本域

我可以使用Inspect读取这些属性。 但是,我无法在C#中使用以下命令找到它:

AutomationElement ae = root.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "Database"), new PropertyCondition(AutomationElement.LocalizedControlTypeProperty, "edit"));

实际上,我可以找到它的唯一方法是通过以下命令(在树之后):

AutomationElement ae = root.FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[2]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[2]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[0];

不幸的是,当我尝试编辑该值时,我收到一条错误消息,提示所选元素是只读的。 但是,该元素实际上不是只读的。 同样,该元素没有应具有的automationId。 使用UIAutomation查看时,树中的任何元素都没有AutomationId。

我尝试自动化的应用程序是专有应用程序,这是我第一次遇到此问题。 我不确定是什么原因引起的,我会调查什么?

编辑:作为一个更新,我能够使用root.FindAll(TreeScope.Descendants,Condition.TrueCondition)的索引成功找到所需的元素。

但是,我有以下代码:

        cachedElement = findAll[index];
        Console.Write("cachedelement : "); cachedElement.ToConsole();           
        return 0;

如果我只是让程序运行,则尝试将文本写入文本字段时它将失败。 而且,它表明所选元素没有属性(在cachedelement.ToConsole期间)。

有趣的是,如果我在return 0处设置一个断点; (或使用System.Diagnostics.Debugger.Break()),cachedElement.ToConsole()将LCT输出为“ edit”(仍然没有AutomationId),并将文本正确地写入文本字段。 我之所以觉得如此有趣,是因为在调用ToConsole之后设置了断点。 它根本不应该影响正在运行的代码。

根据您的第二个代码示例,您要查找的元素嵌套在树的下方,因此第一个代码示例将永远找不到该元素,因为它仅查看桌面的子级。 如果要从根节点查找元素,则需要对Treescope使用TreeScope.Descendants。 我不建议您使用后代,因为从根元素使用它会很慢,而且很可能会引起堆栈溢出

在最坏的情况下,我使用根元素的子作用域为窗口执行FindFirst,然后使用应用程序根目录的后代。 尽管在具有琐碎用户界面的小型应用程序中,这只能快速起作用。 如果您有诸如带有单元格的网格之类的复杂对象,我建议将FindFirst与子范围一起使用,一直到您要查找的元素,类似于您使用全部查找的方式。

如果您可以发布用于编辑元素的代码,则可以使用有关如何编辑针对您情况的控件的信息来更新此答案。 通常,虽然您将如何编辑文本框控件,但是将使用ValuePattern这样。

  public void SetValue(AutomationElement element, string text)
  {
        var valuePattern = (ValuePattern) element.GetCurrentPattern(ValuePattern.Pattern);
        valuePattern.SetValue(text);
  }

希望这会有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM