WPF UI自动化 - 当有许多元素时,AutomationElement.FindFirst会失败

时间:2010-06-08 22:28:00

标签: wpf ui-automation

我们为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实现,它自己手动地走树...据我所知,这应该有效,因为我的树打印机实用程序功能就是这样,并且没关系,但似乎这是不必要和缓慢的: - (

非常感谢任何帮助

3 个答案:

答案 0 :(得分:2)

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

事实上,你可能会发现,使用{1}}的{​​{1}}实现比使用FindFirst对具有大量子元素的元素更快。如果你在Reflector中查看FindFirst的代码,你会看到它通过在自动化边界上拉动所有符合条件的子项,然后返回它们中的第一个来工作。相比之下,TreeWalker方法只会尝试将单个第一个孩子拉过边界。

答案 1 :(得分:2)

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

当我运行UI Spy时,我会在输出窗口中收到一些错误,当我在树中导航时,会显示有关无效父级的信息。我在代码中解决了我如何为Adorner的AutomationElement提供自动化元素的问题。一旦我修复了错误,UI Spy就不再在输出窗口中显示错误了,我不再从FindFirst方法调用中获得错误。

如果原始海报仍在监控此问题,我会问UI Spy在浏览您的应用程序时遇到任何问题吗?

答案 2 :(得分:-1)

我甚至坚持这个问题,但我只是没有看到我的失败。

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);

......它有效。

迈克尔