C# 使用UI自动化订阅组合框选择更改事件
我是UI自动化方面的新手。C# 使用UI自动化订阅组合框选择更改事件,c#,automation,ui-automation,microsoft-ui-automation,C#,Automation,Ui Automation,Microsoft Ui Automation,我是UI自动化方面的新手。 有一个ComboBox类型的AutomationElement。 我正在寻找一种订阅当组合框更改其名称属性时引发的事件的方法 这就是我试图做的,但它不起作用: Automation.AddAutomationPropertyChangedEventHandler( elementComboBox, TreeScope.Element, new AutomationPropertyChangedEventHandler(OnUIAutomatio
有一个ComboBox类型的AutomationElement。
我正在寻找一种订阅当组合框更改其
名称
属性时引发的事件的方法
这就是我试图做的,但它不起作用:
Automation.AddAutomationPropertyChangedEventHandler(
elementComboBox,
TreeScope.Element,
new AutomationPropertyChangedEventHandler(OnUIAutomationPropChanged),
NameProperty
);
看起来您已经知道如何访问ComboBox元素,所以我们只需设置一个用于检测更改事件的 组合框控件是由以下内容组成的合成对象:
- 外部容器
- 用于输入选择/搜索值的内部编辑控件,当组合框为下拉类型时可用
- 内部ListControl,用于显示ComboBox中包含的项目列表,显示为ComboBox下拉元素的一个图标
支持。
方法返回
列表项
元素的集合:项的名称
属性返回当前选择值
通过AutomationElement识别感兴趣的组合框,何时可以为其ExpandCollapseState
属性更改设置事件处理程序,如下所示:
bool success = SetExpandCollapseEventHandler(elementComboBox);
// [...]
// Remove the handler when you're done with it
RemoveExpandCollapseEventHandler(elementComboBox);
此处,string selectedValue
包含组合框关闭时选择的值:当然,您可以在ExpandCollapseState是
展开的
和合并的
时读取该值,以比较当前值和所选值
► 订阅的: 如果您需要知道在没有使用GUI进行实际用户选择的情况下何时更改/选择组合框列表的任何元素,则可以订阅由
列表的子元素引发的事件。
您只需要一个附加到更大范围的处理程序:TreeScope.Children
警告:由于这些事件需要异步处理,因此会在线程池线程中引发这些事件
这会产生以下后果:
- 无法直接访问UI线程中的控件(需要
BeginInvoke()
)
- 如果/当ComboBox控件被释放(例如,当父窗口关闭时),您必须删除
自动venthandler
,否则您的应用程序将变得不稳定,并且可能会永久性地等待事件从某个元素返回值,而该元素在某一点上不再响应
您可能希望在父窗口关闭时使用处理程序接收通知,然后调用Automation.RemoveAutomationEventHandler
(如图所示),但也可能(根据操作的上下文进行评估)调用该方法
称为:
bool success = SetListItemChangedEventHandler(elementComboBox);
// [...]
// Remove the handler when you're done with it
RemoveListItemChangedHandler();
谢谢当组合框折叠/展开时,您的解决方案非常有效。但是当组合框从外部更改时,事件不会引发。在我的例子中,当用户在另一个控件中选择某些元素时,combobox的项目从外部更改(实际上是在3D空间中,但这并不重要)。每次更改三维空间中的选择时,组合框的项目列表和选定元素也会更改。我需要订阅任何可能通知组合框更改的事件。好吧,您在问题中没有描述任何这些。编辑问题并添加理解场景所需的所有细节。不知道3D空间意味着什么。无论如何,您可能只想订阅ListControl的事件,而不是ComboBox本身(如前所述,ComboBox是一个复合控件)。我添加了一个与List元素的ListItems选择事件相关的部分。Jimi!谢谢你这么详细的回答。这对我很有用。我会尽快在问题中补充资料
bool success = SetListItemChangedEventHandler(elementComboBox);
// [...]
// Remove the handler when you're done with it
RemoveListItemChangedHandler();
private AutomationElement listElement = null;
private AutomationEventHandler ListItemChangedHandler = null;
public bool SetListItemChangedEventHandler(AutomationElement combobox)
{
listElement = combobox.FindFirst(TreeScope.Children,
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.List));
if ((bool)listElement.GetCurrentPropertyValue(AutomationElement.IsSelectionPatternAvailableProperty)) {
Automation.AddAutomationEventHandler(SelectionItemPattern.ElementSelectedEvent,
listElement, TreeScope.Children,
ListItemChangedHandler = new AutomationEventHandler(OnListItemChanged));
return true;
}
return false;
}
private void OnListItemChanged(object elm, AutomationEventArgs e)
{
string selectedValue = (elm as AutomationElement)?.Current.Name;
}
private void RemoveListItemChangedHandler()
{
Automation.RemoveAutomationEventHandler(
SelectionItemPattern.ElementSelectedEvent, listElement, ListItemChangedHandler);
ListItemChangedHandler = null;
}