使用UI自动化选择自定义ComboBox项

时间:2019-04-29 12:54:47

标签: c# wpf xaml combobox microsoft-ui-automation

如何使用Microsoft UI Automation在自定义ComboBox中选择一个项目?我有一个看起来像这样的ComboBox:

<ComboBox AutomationProperties.AutomationId="Rm8Function"
          ItemsSource="{Binding Source={StaticResource Functions}}"
          SelectedItem="{Binding Function, UpdateSourceTrigger=PropertyChanged}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock
                Text="{Binding Mode=OneTime, Converter={StaticResource FunctionEnumConverter}}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

即我已经使用自定义DataTemplate覆盖了ItemTemplate。

但是,现在我无法使用selecting combobox item using ui automation上的答案来选择项目:

public static void SelectComboBoxItem(this AutomationElement comboBox, string item)
{
    var expandCollapsePattern = comboBox.GetPattern<ExpandCollapsePattern>(ExpandCollapsePatternIdentifiers.Pattern);
    expandCollapsePattern.Expand();
    expandCollapsePattern.Collapse();
    var listItem = comboBox.FindFirst(TreeScope.Subtree,
        new PropertyCondition(AutomationElement.NameProperty, item));
    var selectionItemPattern = listItem.GetPattern<SelectionItemPattern>(SelectionItemPatternIdentifiers.Pattern);
    selectionItemPattern.Select();
}

public static T GetPattern<T>(this AutomationElement element, AutomationPattern pattern) where T: BasePattern
{
    try
    {
        return (T) element.GetCurrentPattern(pattern);
    }
    catch (InvalidOperationException)
    {
        element.PrintSupportedPatterns();
        throw;
    }
}

它抛出一个错误,告诉我SelectionItemPatternIdentifiers.Pattern是不受支持的模式。尝试在ComboBox中选择的元素仅支持SynchronizedInputPatternIdentifiers.Pattern

我应该如何编写我的DataTemplate以便使其成为可选的?

1 个答案:

答案 0 :(得分:0)

我通过以下方式重新定义了ComboBox

<ComboBox AutomationProperties.AutomationId="Rm8Function"
          ItemsSource="{Binding Source={StaticResource Functions}}"
          SelectedItem="{Binding Function, UpdateSourceTrigger=PropertyChanged}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock
                AutomationProperties.Name="{Binding Mode=OneTime, Converter={StaticResource FunctionEnumConverter}}"
                Text="{Binding Mode=OneTime, Converter={StaticResource FunctionEnumConverter}}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

TextBlock提供与其AutomationProperties.Name相同的Text值。

我还将选择ComboBox项的功能更新为以下内容:

public static void SelectComboBoxItem(this AutomationElement comboBox, string item)
{
    var expandCollapsePattern = comboBox.GetPattern<ExpandCollapsePattern>(ExpandCollapsePatternIdentifiers.Pattern);
    expandCollapsePattern.Expand();
    expandCollapsePattern.Collapse();
    var listItem = comboBox.FindFirst(TreeScope.Subtree,
        new PropertyCondition(AutomationElement.NameProperty, item));
    var walker = TreeWalker.ControlViewWalker;
    var parent = walker.GetParent(listItem);
    while (parent != comboBox)
    {
        listItem = parent;
        parent = walker.GetParent(listItem);
    }
    var selectionItemPattern = listItem.GetPattern<SelectionItemPattern>(SelectionItemPatternIdentifiers.Pattern);
    selectionItemPattern.Select();
}

显然,当按原样使用ComboBox而不覆盖ItemTemplate时,以上函数会找到其直接子元素ListBoxItem。可以通过ListBoxItem模式选择SelectionItemPattern。但是,当覆盖ItemTemplate时,该函数会找到TextBlock的子项ListBoxItem。因此,我必须以某种方式修改函数,使其向上遍历,直到找到ComboBox的直接子节点并将其选中为止。