Vb.net UI自动化-从SysListView32(或任何Listview)检索数据

Vb.net UI自动化-从SysListView32(或任何Listview)检索数据,vb.net,listview,ui-automation,inspector,automationelement,Vb.net,Listview,Ui Automation,Inspector,Automationelement,我试图用下面的代码从SysListView32对象检索数据,但它返回的是空字符串 我需要检索的元素是那些以红色突出显示的元素,以及其他ControlType.ListItem元素中包含的其他元素,根据Inspector的打印 有人能检查一下我的代码有什么问题吗 如果SysListView32的当前视图状态不是,那么它可能不会提供所请求的信息,因此我们应该暂时(如果当前视图状态不同),使用其AutomationElement的验证视图状态,并在必要时使用该方法对其进行更改 SetCurrentV

我试图用下面的代码从SysListView32对象检索数据,但它返回的是空字符串

我需要检索的元素是那些以红色突出显示的元素,以及其他
ControlType.ListItem
元素中包含的其他元素,根据Inspector的打印

有人能检查一下我的代码有什么问题吗


如果SysListView32的当前视图状态不是,那么它可能不会提供所请求的信息,因此我们应该暂时(如果当前视图状态不同),使用其AutomationElement的验证视图状态,并在必要时使用该方法对其进行更改

SetCurrentView()
方法使用与Win32控件相同的值

然后使用的AutomationElement方法查找或
ControlType.ListItem
(使用)类型的所有子元素

对于每个控件,获取类型为
ControlType.Edit
ControlType.Text
(使用另一个
或条件)的所有子项

列表中每个项的位置都是使用项的属性来检索的,以访问该项的属性

最后,如果必须更改,我们将恢复以前的视图状态


示例中的代码填充一个
字典(整数,ListViewItem)
sysListViewItems
),其中包含从SysListView32中提取的所有项

  • 整数键表示项目在原始ListView中的位置
  • ListViewItem是一个.Net对象,它是从每个项提取的值数组(作为字符串)生成的
如果您不需要ListViewItem对象,只需存储由对象表示的列表(字符串)
,而不是在此处创建ListViewItem:

sysListViewItems.Add(gridPattern.Current.Row, New ListViewItem(itemsText.ToArray())).  
SysListView32的句柄也可以通过
ClassName

提供当前桌面元素:

Dim parentWindow = AutomationElement.RootElement.FindFirst(
    TreeScope.Children, New PropertyCondition(AutomationElement.NameProperty, "[Window Caption]"))
Dim sysListView32 = parentWindow.FindAll(
    TreeScope.Subtree, New PropertyCondition(AutomationElement.ClassNameProperty, "SysListView32"))
如果找到多个SysListView32,请按标题内容、直接父级
ControlType
ClassName
或任何允许将其挑出的内容进行筛选

UI自动化需要引用
UIAutomationClient
UIAutomationTypes
程序集


导入System.Windows.Automation
Dim sysListViewHandle=[GetSysListView32Handle()]
Dim sysListViewElement=AutomationElement.FromHandle(sysListViewHandle)
如果sysListViewElement为Nothing,则返回
Dim sysListViewItems=新字典(整数的,ListViewItem)()
将多视图调整为多视图模式=无
将图案变暗为对象=无
Dim currentView作为整数=-1
如果是sysListViewElement.TryGetCurrentPattern(MultipleViewPattern.Pattern,Pattern),则
mulView=DirectCast(模式,多视图模式)
currentView=mulView.Current.currentView
如果currentView ListViewWSState.LV\u查看\u详细信息,则
mulView.SetCurrentView(ListViewWState.LV\u视图详细信息)
如果结束
如果结束
Dim childItemsCondition=新的或条件(
新属性条件(AutomationElement.ControlTypeProperty、ControlType.DataItem),
新属性条件(AutomationElement.ControlTypeProperty、ControlType.ListItem))
Dim childItems=sysListViewElement.FindAll(TreeScope.Children,childItemsCondition)
如果childItems.Count=0,则返回
Dim子项条件=新的或条件(
新属性条件(AutomationElement.ControlTypeProperty、ControlType.Edit),
新属性条件(AutomationElement.ControlTypeProperty、ControlType.Text))
作为子项中的AutomationElement的每个项
Dim itemsText=新列表(字符串)()
Dim subItems=item.FindAll(TreeScope.Children,subItemsCondition)
将每个子项作为子项中的AutomationElement
itemsText.Add(subItem.Current.Name)
下一个
Dim gridPattern=DirectCast(子项(0).GetCurrentPattern(GridItemPattern.Pattern),GridItemPattern)
添加(gridPattern.Current.Row,新的ListViewItem(itemsText.ToArray()))
下一个
如果mulView不是什么,那么
mulView.SetCurrentView(currentView)
如果结束
好友枚举ListViewState
LV_视图_图标=&H0
LV\U视图\U详细信息=&H1
LV\u视图\u小图标=&H2
LV\U视图\U列表=&H3
LV_视图_平铺=&H4
结束枚举
Dim parentWindow = AutomationElement.RootElement.FindFirst(
    TreeScope.Children, New PropertyCondition(AutomationElement.NameProperty, "[Window Caption]"))
Dim sysListView32 = parentWindow.FindAll(
    TreeScope.Subtree, New PropertyCondition(AutomationElement.ClassNameProperty, "SysListView32"))
Imports System.Windows.Automation

Dim sysListViewHandle = [GetSysListView32Handle()]

Dim sysListViewElement = AutomationElement.FromHandle(sysListViewHandle)
If sysListViewElement Is Nothing Then Return

Dim sysListViewItems = New Dictionary(Of Integer, ListViewItem)()
Dim mulView As MultipleViewPattern = Nothing
Dim pattern As Object = Nothing
Dim currentView As Integer = -1

If sysListViewElement.TryGetCurrentPattern(MultipleViewPattern.Pattern, pattern) Then
    mulView = DirectCast(pattern, MultipleViewPattern)
    currentView = mulView.Current.CurrentView
    If currentView <> ListViewWState.LV_VIEW_DETAILS Then
        mulView.SetCurrentView(ListViewWState.LV_VIEW_DETAILS)
    End If
End If

Dim childItemsCondition = New OrCondition(
    New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.DataItem),
    New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ListItem))

Dim childItems = sysListViewElement.FindAll(TreeScope.Children, childItemsCondition)
If childItems.Count = 0 Then Return

Dim subItemsCondition = New OrCondition(
    New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit),
    New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Text))

For Each item As AutomationElement In childItems
    Dim itemsText = New List(Of String)()
    Dim subItems = item.FindAll(TreeScope.Children, subItemsCondition)
    For Each subItem As AutomationElement In subItems
        itemsText.Add(subItem.Current.Name)
    Next
    Dim gridPattern = DirectCast(subItems(0).GetCurrentPattern(GridItemPattern.Pattern), GridItemPattern)
    sysListViewItems.Add(gridPattern.Current.Row, New ListViewItem(itemsText.ToArray()))
Next

If mulView IsNot Nothing Then
    mulView.SetCurrentView(currentView)
End If

Friend Enum ListViewWState
    LV_VIEW_ICON = &H0
    LV_VIEW_DETAILS = &H1
    LV_VIEW_SMALLICON = &H2
    LV_VIEW_LIST = &H3
    LV_VIEW_TILE = &H4
End Enum