TreeWalker перемещает элементы управления из другого окна
Я работаю с окном приложения, содержащим много сообщений журнала. Мне нужно отфильтровать их и получить только те, которые соответствуют некоторым условиям. Мой выбор пройти их все TreeWalker
как фильтрация полной массы сообщений после AutomationElement.GetAll()
слишком дорого (может быть тысячи сообщений).
List<AutomationElement> messages = new List<AutomationElement>();
TreeWalker walker = new TreeWalker(new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.DataItem));
AutomationElement row = walker.GetFirstChild(parentDatagrid);
while (row != null)
{
if (/*some condition*/)
messages.Add(row);
row = walker.GetNextSibling(row);
}
Вот UISpy-представление иерархии элементов управления, которое я тестирую.
Неожиданно messages
длина больше, чем фактическое количество сообщений журнала. Я запросил дополнительные элементы автоматизации UISpy и обнаружил, что эти элементы были получены из другого окна (они также соответствовали условию ControlTypeProperty = ControlType.DataItem
). Более того, это окно принадлежало даже другому приложению. TreeWalker
закончил свой поиск в объеме parentDatagrid
и продолжал обходить всю настольную иерархию.
Конечно, я надеялся получить только дочерние элементы datagrid. Что может вызвать такие странные TreeWalker
поведение? Возможно, мой код неверен, но я написал один и тот же отрывок несколько раз, и он работал правильно.
2 ответа
На самом деле я не могу сказать вам, почему TreeWalker делает это, потому что я никогда не использую TreeWalker для навигации. Я просто использую его для поиска родителей, детей, братьев и сестер и т.д..
Что я могу вам сказать, так это то, что у меня очень хороший опыт использования следующего:
List<AutomationElement> messages = new List<AutomationElement>();
AutomationElement parentDatagrid;//your AE
Condition yourCond = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.DataItem));
AutomationElementCollection aECollection;
aECollection= parentDatagrid.FindAll(TreeScope.Element | TreeScope.Descendants, yourCond);
foreach (AutomationElement element in aECollection)
{
//whatever you like
}
конечно, вы должны быть осторожны с TreeScope.Descendants, если производительность является проблемой. Тогда вам следует вместо этого рассмотреть TreeScope.Children, поскольку потомки смотрят на все подэлементы, а дочерние - только на прямые дочерние элементы.
надеюсь это поможет!
Когда вы создаете пользовательский TreeWalker
Как и вы, поведение будет таким, как вы упомянули. Может быть, лучше использовать TreeWalker.ControlViewWalker
а затем проверьте каждый из найденных элементов для вашего состояния.