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-представление иерархии элементов управления, которое я тестирую.

Скриншот из 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 а затем проверьте каждый из найденных элементов для вашего состояния.

Другие вопросы по тегам