使用ui自动化选择组合框项目

时间:2011-04-28 06:54:16

标签: c# wpf

如何选择 ComboBox的SelectedIndex = -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

9 个答案:

答案 0 :(得分:23)

这比它需要的复杂<100>复杂,但我终于开始工作了。 WPF ComboBox的一个大问题是,就自动化而言,它似乎没有任何ListItems ,直到ComboBox扩展

以下代码使用ExpandCollapse模式暂时下拉列表然后折叠它,然后它可以在ComboBox上使用FindFirst来获取ListItem,然后使用SelectionItem模式来选择它。

对于原始问题,选择-1表示未选择任何项目。没有方法,但您可以简单地使用FindAll获取ListItems的集合,依次获取每个ListItem的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;
    }

答案 1 :(得分:2)

我想我会分享这个作为从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或item容器,item是容器中项目的字符串名称或文字值。获得该项目后,您可以执行以下操作选择它:

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

希望这有助于他人。我从自动化的MSDN文档中获得了这种模式,在这里找到:

MSDN - Automation and Cached Children

答案 2 :(得分:2)

这对我有用。

    /// <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

答案 3 :(得分:1)

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

这是我理解的问题的答案。

但是......这真的是你的问题吗?

无论如何,你可以从一个选择中添加或删除SelectableItems - 我想 - 它属于它的父级,同样可以用来检查它们是否被选中。

答案 4 :(得分:1)

我认为这可能是简单的通用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();
}

答案 5 :(得分:1)

没有太大变化,只有少数人需要注意,

  1. 不需要使用崩溃模式,调用expand会为你做到这一点。
  2. 使用treescope.subtree为我而不是孩子工作。
  3. 代码示例就像这样,

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

答案 6 :(得分:0)

对我来说,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;
        }

答案 7 :(得分:0)

<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 AutomationElement 3)Utility.SetCombox(ComboxAutomationElement,“ SelectedText”)

要了解:

ComboBox的树结构如下:

ComboBox-> ListBox(子级)-> ListItems(子级)[每个组合框都有一个ListBox作为子级,而ListBox则具有所有ListItems作为子级]。

每个ListItem具有SelectedItemPattern,调用您要选择的项目。

我后来发现“ Shaz”具有更好的编码,我将他评为最佳编码。

**注释:要执行UIAAutomation,必须将应用程序的AutomationElement映射到TreeView,这使一切变得简单易懂。

答案 8 :(得分:0)

我在 WindowsForms comboBox

中使用了此代码

用法

comboBox.SetSelectedComboBoxItem("ValueYouWantToSelect");

将此Class添加到您的项目中:

public static class AutomationElementExtensions
    { 
        public static void InvokeControl(this AutomationElement element)
        {
            InvokePattern invokePattern = null;

            try
            {
                invokePattern =
                    element.GetCurrentPattern(InvokePattern.Pattern)
                    as InvokePattern;
            }
            catch (ElementNotEnabledException)
            {
                // Object is not enabled
                return;
            }
            catch (InvalidOperationException)
            {
                // object doesn't support the InvokePattern control pattern
                return;
            }

            invokePattern.Invoke();
            Thread.Sleep(500);
        } 


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

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

            expandCollapsePattern.Expand();



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

            InvokeControl(listItem); 
        }

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


    }