Select 具有 UI 自动化的自定义 ComboBox 项目
Select custom ComboBox item with UI Automation
如何使用 Microsoft UI 自动化 select 自定义组合框中的项目?我的 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。
但是,现在我无法 select 使用 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
是一个不受支持的模式。只有 SynchronizedInputPatternIdentifiers.Pattern
受其试图在 ComboBox 中 select 的元素支持。
我应该如何编写我的 DataTemplate 才能使其 select 可用?
我按以下方式重新定义了我的 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
与其 Text
值相同的 AutomationProperties.Name
值。
我还将选择 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
。可以通过 SelectionItemPattern
模式选择 ListBoxItem
。但是当覆盖 ItemTemplate
时,该函数反而会找到 TextBlock
,它是 ListBoxItem
的子项。因此,我不得不修改我的函数,使其向上遍历,直到找到 ComboBox
的直接子节点并选择它。
如何使用 Microsoft UI 自动化 select 自定义组合框中的项目?我的 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。
但是,现在我无法 select 使用 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
是一个不受支持的模式。只有 SynchronizedInputPatternIdentifiers.Pattern
受其试图在 ComboBox 中 select 的元素支持。
我应该如何编写我的 DataTemplate 才能使其 select 可用?
我按以下方式重新定义了我的 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
与其 Text
值相同的 AutomationProperties.Name
值。
我还将选择 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
。可以通过 SelectionItemPattern
模式选择 ListBoxItem
。但是当覆盖 ItemTemplate
时,该函数反而会找到 TextBlock
,它是 ListBoxItem
的子项。因此,我不得不修改我的函数,使其向上遍历,直到找到 ComboBox
的直接子节点并选择它。