выбор элемента комбинированного списка с помощью автоматизации пользовательского интерфейса - PullRequest
9 голосов
/ 28 апреля 2011

как выбрать SelectedIndex ComboBox = -1?

Я написал код для автоматизации тестирования:

AutomationElement aeBuildMachine = null;
int count = 0;
do
{
    Console.WriteLine("\nLooking for Build Machine Combo Box");
    aeBuildMachine = aeTabitemmain.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.ClassNameProperty, "ListBoxItem"));
    if (aeBuildMachine == null)
          throw new Exception("No Build Machine Combo Box");
    else
          Console.WriteLine("Found Build Machine Combo Box");
    ++count;
 }
while (aeBuildMachine == null && count < 50);

Console.WriteLine("Selecting Build machine from combobox...");
SelectionItemPattern spBuildmachine = (SelectionItemPattern)aeBuildMachine.GetCurrentPattern(SelectionItemPattern.Pattern);

Как мне использовать это SelectionItemPattern?

Ответы [ 8 ]

23 голосов
/ 17 января 2012

Это примерно в 100 раз сложнее , чем нужно, но я наконец-то все заработало.Большая проблема с WPF ComboBox заключается в том, что с точки зрения автоматизации у него нет ListItems до тех пор, пока ComboBox не будет расширен .

В следующем коде используется шаблон ExpandCollapse.чтобы на мгновение раскрыть список и затем свернуть его, затем он может использовать FindFirst в ComboBox, чтобы получить ListItem, который будет выбран, и затем использовать шаблон SelectionItem, чтобы выбрать его.

В случае исходного вопросавыбор -1 означает, что элементы не выбраны.Для этого нет метода, но вы можете просто использовать FindAll, чтобы получить коллекцию ListItems, получить шаблон SelectionItem для каждого по очереди и вызвать его метод RemoveFromSelection.

    public static void SetSelectedComboBoxItem(AutomationElement comboBox, string item)
    {
        AutomationPattern automationPatternFromElement = GetSpecifiedPattern(comboBox, "ExpandCollapsePatternIdentifiers.Pattern");

        ExpandCollapsePattern expandCollapsePattern = comboBox.GetCurrentPattern(automationPatternFromElement) as ExpandCollapsePattern;

        expandCollapsePattern.Expand();
        expandCollapsePattern.Collapse();

        AutomationElement listItem = comboBox.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.NameProperty, item));

        automationPatternFromElement = GetSpecifiedPattern(listItem, "SelectionItemPatternIdentifiers.Pattern");

        SelectionItemPattern selectionItemPattern = listItem.GetCurrentPattern(automationPatternFromElement) as SelectionItemPattern;

        selectionItemPattern.Select();
    }

    private static AutomationPattern GetSpecifiedPattern(AutomationElement element, string patternName)
    {
        AutomationPattern[] supportedPattern = element.GetSupportedPatterns();

        foreach (AutomationPattern pattern in supportedPattern)
        {
            if (pattern.ProgrammaticName == patternName)
                return pattern;
        }

        return null;
    }
2 голосов
/ 07 июля 2016

Это то, что сработало для меня.

    /// <summary>
    /// Extension method to select item from comboxbox
    /// </summary>
    /// <param name="comboBox">Combobox Element</param>
    /// <param name="item">Item to select</param>
    /// <returns></returns>
    public static bool SelectComboboxItem(this AutomationElement comboBox, string item)
    {
        if (comboBox == null) return false;
        // Get the list box within the combobox
        AutomationElement listBox = comboBox.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.List));
        if (listBox == null) return false;
        // Search for item within the listbox
        AutomationElement listItem = listBox.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, item));
        if (listItem == null) return false;
        // Check if listbox item has SelectionItemPattern
        object objPattern;
        if (true == listItem.TryGetCurrentPattern(SelectionItemPatternIdentifiers.Pattern, out objPattern))
        {
            SelectionItemPattern selectionItemPattern = objPattern as SelectionItemPattern;
            selectionItemPattern.Select(); // Invoke Selection
            return true;
        }
        return false;
    }

Использование

        AutomationElement paymentCombobox = element.FindFirst(
            TreeScope.Children,
            new PropertyCondition(AutomationElement.NameProperty, "cbPayment")
        );
        paymentCombobox.SelectComboboxItem("Cash");

ресурс https://msdn.microsoft.com/en-us/library/ms752305(v=vs.110).aspx

2 голосов
/ 31 января 2013

Я подумал, что поделюсь этим как простым способом выбрать любой элемент из ComboBox или другого контейнера элемента:

protected AutomationElement GetItem(AutomationElement element, string item)
    {
        AutomationElement elementList;
        CacheRequest cacheRequest = new CacheRequest();
        cacheRequest.Add(AutomationElement.NameProperty);
        cacheRequest.TreeScope = TreeScope.Element | TreeScope.Children;

        elementList = element.GetUpdatedCache(cacheRequest);

        foreach (AutomationElement child in elementList.CachedChildren)
            if (child.Cached.Name == item)
                return child;

        return null;
    }

элемент - это ComboBox или контейнер элемента, элемент - имя строки или буквальное значение элемента в контейнере. Если у вас есть предмет, вы можете сделать следующее, чтобы выбрать его:

protected void Select(AutomationElement element)
    {
        SelectionItemPattern select = (SelectionItemPattern)element.GetCurrentPattern(SelectionItemPattern.Pattern);
        select.Select();
    }

Надеюсь, это поможет другим. Я получил этот шаблон из документации MSDN по автоматизации, найденной здесь:

MSDN - Автоматизация и кэшированные дочерние элементы

1 голос
/ 18 сентября 2017

Нет больших изменений, но есть только несколько, чтобы заметить,

  1. Не нужно использовать шаблон коллапса, вызов расширения поможет вам.
  2. Использование treescope.subtree сработало для меня вместо детей.

Пример кода будет таким,

public static void SelectValueInComboBox(string comboBox, string value)
{
    var comboBoxElement = HelperMethods.FindElementFromAutomationID(comboBox);
    if (comboBoxElement == null)
        throw new Exception("Combo Box not found");

    ExpandCollapsePattern expandPattern = (ExpandCollapsePattern)comboBoxElement.GetCurrentPattern(ExpandCollapsePattern.Pattern);

    AutomationElement comboboxItem = comboBoxElement.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.NameProperty, value));

    SelectionItemPattern selectPattern = (SelectionItemPattern)comboboxItem.GetCurrentPattern(SelectionItemPattern.Pattern);
    selectPattern.Select();
}
1 голос
/ 03 июля 2015

Я думаю, что это может быть самый простой способ для простого универсального установщика значений ComobBox, это хорошо, если элементы списка в ComboBox не имеют дубликатов.

private void SetCombobValueByUIA( AutomationElement ctrl, string newValue )
{ 
    ExpandCollapsePattern exPat = ctrl.GetCurrentPattern(ExpandCollapsePattern.Pattern) 
                                                              as ExpandCollapsePattern;

    if( exPat== null )
    {
        throw new ApplicationException( "Bad Control type..." );
    }

    exPat.Expand();

    AutomationElement itemToSelect = ctrl.FindFirst(TreeScope.Descendants, new
                          PropertyCondition(AutomationElement.NameProperty,newValue));

    SelectionItemPattern sPat = itemToSelect.GetCurrentPattern(
                                              SelectionItemPattern.Pattern)  as SelectionItemPattern ; 
    sPat. Select();
}
1 голос
/ 30 мая 2011

http://msdn.microsoft.com/de-de/library/system.windows.automation.selectionitempattern_members(v=VS.85).aspx

Это ответ на ваш вопрос, как я понял.

Но .. это действительно твой вопрос?

В любом случае, вы можете добавлять или удалять SelectableItems из выбора, который - я полагаю - принадлежит его родителю, то же самое касается некоторых других вещей, таких как проверка, выбраны ли они.

0 голосов
/ 30 января 2019
<pre>
  public static void SetComboBox(AutomationElement ComboxBox, string SelectedValue)
        {
            AutomationElement ListBox = ComboxBox.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "ListBox"));
            AutomationElement SelectedItem = ListBox.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, SelectedValue));
            ((SelectionItemPattern)SelectedItem.GetCurrentPattern(SelectionItemPattern.Pattern)).Select();
        }

Инструкция по применению: 1) Скопируйте и вставьте в служебный класс 2) Найдите свой элемент автоматизации ComboBox 3) Utility.SetCombox (ComboxAutomationElement, "SelectedText")

Чтобы понять:

Древовидная структура ComboBox выглядит следующим образом:

ComboBox-> ListBox (children) -> ListItems (children) [каждый комбинированный список имеет ListBox как дочерний элемент, а ListBox имеет все ListItems как дочерние].

Каждый ListItem имеет SelectedItemPattern, вызывайте который вы хотите выбрать.

Позже я узнал, что код "Шаз" лучше кодируется, и я оцениваю его как лучший код.

** Комментарий: чтобы выполнить UIAAutomation, вы должны отобразить элементы автоматизации вашего приложения в TreeView, что делает все простым и понятным.

0 голосов
/ 17 января 2019

Для меня ответ от gotmug требовал активации CacheRequest. Я реализовал это как метод расширения

 public static bool SelectDropDownItem(this AutomationElement comboBoxElement, string item)
        {
            bool itemFound = false;
            AutomationElement elementList;
            CacheRequest cacheRequest = new CacheRequest();
            cacheRequest.Add(AutomationElement.NameProperty);
            cacheRequest.TreeScope = TreeScope.Element | TreeScope.Children;

            using (cacheRequest.Activate())
            {
                // Load the list element and cache the specified properties for its descendants.
                Condition cond = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.List);
                elementList = comboBoxElement.FindFirst(TreeScope.Children, cond);
            }

            //Loop thru and find the actual ListItem
            foreach (AutomationElement child in elementList.CachedChildren)
                if (child.Cached.Name == item)
                {
                    SelectionItemPattern select = (SelectionItemPattern)child.GetCurrentPattern(SelectionItemPattern.Pattern);
                    select.Select();
                    itemFound = true;
                    break;
                }
            return itemFound;
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...