【问题标题】:WPF UI Automation - AutomationElement.FindFirst fails when there are lots of elementsWPF UI 自动化 - 当有很多元素时,AutomationElement.FindFirst 失败
【发布时间】:2011-01-06 21:23:38
【问题描述】:

我们为 WPF 应用程序 (.NET 4) 进行了一些自动化 UI 测试;这些测试使用UI Automation API。

我们调用AutomationElement.FindFirst寻找目标元素,然后与之交互。

示例(伪代码):

var nameEquals = new PropertyCondition(AutomationElement.NameProperty, "OurAppWindow");
var appWindow = DesktopWindow.FindFirst(TreeScope.Children, nameEquals);
// this succeeds

var idEquals = new PropertyCondition(AutomationElement.AutomationIdProperty, "ControlId");
var someItem = appWindow.FindFirst(TreeScope.Descendants, idEquals);
// this suceeds sometimes, and fails sometimes!

问题是,appWindow.FindFirst 有时会失败并返回 null,即使元素存在也是如此。我编写了一个辅助函数,它手动遍历 UI 自动化树并将其打印出来,并且在所有情况下都存在具有正确 ID 的元素。

这似乎与窗口中还显示了多少其他项目有关。如果没有其他项目,那么它总是会成功,但是当它旁边显示许多其他复杂的 UI 元素时,则查找失败。

似乎我们正在达到某种内部元素限制。我找不到任何自动化 API 提到的任何记录的元素限制 - 有没有办法解决这个问题?我在想我可能必须编写自己的FindFirst 实现,它自己手动行走树...据我所知,这应该可以工作,因为我的树打印机实用程序功能正是这样做的,没关系,但似乎这是不必要且缓慢的:-(

任何帮助将不胜感激

【问题讨论】:

  • 我从几天前就开始使用 UI 自动化框架工作了,我发现有多少错误真的很遗憾。它在所有级别上都充满了错误。微软做了一件非常草率的工作。但是错误似乎在框架的服务器端,因为如果您自动化 Win32 或 WPF 或 .NET Forms 应用程序,它会产生很大的不同。根据底层 UI 框架,您会遇到其他类型的错误。此外,许多控件根本不受支持,或者功能太基本以至于您无法自动化它们。

标签: wpf ui-automation


【解决方案1】:

手动执行树遍历可能是解决此问题的最佳方法。

事实上,您可能会发现使用树遍历实现FindFirst 会比在具有大量子元素的元素上使用FindFirst 更快。如果您查看 Reflector 中 AutomationElement.FindFirst 的代码,您会发现它的工作原理是将所有匹配条件的子项拉过自动化边界,然后返回其中的第一个。相比之下,TreeWalker 方法只会尝试将单个第一个孩子拉过边界。

【讨论】:

  • 这就是我最终要做的,不过我没有使用任何 UI 自动化 TreeWalkers,我只是做了一个递归 foreach(child in x.children)。太慢了,所以我会考虑使用 TreeWalker 类,看看是否有帮助
【解决方案2】:

我在自动化的一个应用程序中遇到了同样的问题。我在 AdornerLayer 上有一个自定义控件,并且我正在修改 UI 自动化树,因此 Adorner 的 AutomationElement 显示为它正在装饰的控件的 UI Visual 子项,而不是显示为应用程序根的子项。

当我运行 UI Spy 时,当我在其树中导航时,我会在输出窗口中看到一些错误,说明有关无效父级的信息。我解决了我的代码中的一个错误,即我如何为 Adorner 的 AutomationElement 设置 AutomationElement。一旦我修复了这个错误,UI Spy 就不再在输出窗口中显示错误,并且我不再从 FindFirst 方法调用中得到失败。

如果原始发布者仍在监视这个问题,我会问 UI Spy 在浏览您的应用程序时是否有任何问题?

【讨论】:

  • 从哪里获得 UISpy?我从来没有找到下载它:-(
  • 您必须通过 Microsoft 将其作为 SDK 的一部分下载。在这里尝试:microsoft.com/downloads/en/… 并且根据某人的说法,您只需要选择“.NET 开发工具”。我从另一个完整的 SDK 下载中获得了 UISpy。
【解决方案3】:

我什至遇到了这个问题,但我只是没有看到我的失败。

var window = new System.Windows.Window();
window.Show();
window.Content = addControl;
GetWindow(window.Name);

我创建了一个窗口并添加了控件作为窗口的内容。我在这里的失败是,我显示了窗口,然后分配了内容。这甚至失败了。经过数小时的搜索,我将代码更改为:

var window = new System.Windows.Window();
window.Content = addControl;
window.Show();
GetWindow(window.Name);

...它的工作原理。

迈克尔

【讨论】:

  • 真可惜!你连问题都没看懂!
猜你喜欢
  • 1970-01-01
  • 2019-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-03
  • 2011-09-15
  • 2017-12-05
相关资源
最近更新 更多