如果当前视图状态不是 SysListView32 可能无法提供请求的信息LV_VIEW_DETAILS
,因此我们应该暂时(如果当前视图状态不同)使用其 AutomationElement 的MultipleViewPattern来验证视图状态,并在必要时使用MultipleViewPattern 进行更改。 SetCurrentView()方法。
该SetCurrentView()
方法使用 Win32 控件的相同值。
然后使用 AutomationElement FindAll()方法查找ControlType.DataItem或ControlType.ListItem
(使用OrCondition)类型的所有子元素。
对于它们中的每一个,获取类型ControlType.Edit
和ControlType.Text
(使用另一个OrCondition
)的所有子项。
使用 Item 的GridItemPattern检索列表中每个 Item 的位置,以访问 Item 的Row属性。
最后,如果我们必须更改它,我们将恢复之前的视图状态。
示例中的代码填充了一个Dictionary(Of Integer, ListViewItem)
( sysListViewItems
),其中包含从 SysListView32 中提取的所有项目。
- Integer Key表示一个Item在原始ListView中的位置
- ListViewItem 是从每个项目中提取的值数组(作为字符串)生成的 .Net 对象。
如果您不需要 ListViewItem 对象,您可以只存储List(Of String)
由该itemsText
对象表示的 ,而不是在此处创建 ListViewItem :
sysListViewItems.Add(gridPattern.Current.Row, New ListViewItem(itemsText.ToArray())).
SysListView32 的句柄也可以通过枚举其顶级窗口的子级来获取ClassName
。
AutomationElement.RootElement提供当前的桌面元素:
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,请按 Header 内容、直接父项ControlType
或ClassName
任何其他允许将其单独列出的内容进行过滤。
UI 自动化需要对UIAutomationClient
和UIAutomationTypes
程序集的引用。
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