在下图中,有一个区域,其中有一个未知(自定义)类。那不是网格或表格。
我需要能够:
- 选择此区域中的行
- 从每个单元格中获取一个值
问题是因为这不是一个常见的类型元素 - 我不知道如何用谷歌搜索这个问题或自己解决它。到目前为止,代码如下:
Process[] proc = Process.GetProcessesByName("programname");
AutomationElement window = AutomationElement.FromHandle(proc [0].MainWindowHandle);
PropertyCondition xEllist2 = new PropertyCondition(AutomationElement.ClassNameProperty, "CustomListClass", PropertyConditionFlags.IgnoreCase);
AutomationElement targetElement = window.FindFirst(TreeScope.Children, xEllist2);
我已经尝试将这个区域作为一个文本框、一个网格、一个组合框来威胁,但到目前为止还没有解决我的问题。有人对如何从该区域获取数据并遍历行有任何建议吗?
编辑:对不起,我做了一个错误的假设。实际上,该区域的标题(第 1 列、第 2 列、第 3 列)和“下半部分”是不同的控件类型!
感谢 Wininspector,我能够挖掘有关这些控件类型的更多信息:
- 标头具有以下属性: HeaderControl 0x056407DC (90441692) Atom: #43288 0xFFFFFFFF (-1)
- 下半部分有这些: ListControl 0x056408A4 (90441892) Atom: #43288 0x02A6FDA0 (44498336)
我之前展示的代码 - 仅检索“列表”元素,所以这里是更新:
Process[] proc = Process.GetProcessesByName("programname");
AutomationElement window = AutomationElement.FromHandle(proc [0].MainWindowHandle);
//getting the header
PropertyCondition xEllist3 = new PropertyCondition(AutomationElement.ClassNameProperty, "CustomHeaderClass", PropertyConditionFlags.IgnoreCase);
AutomationElement headerEl = XElAE.FindFirst(TreeScope.Children, xEllist3);
//getting the list
PropertyCondition xEllist2 = new PropertyCondition(AutomationElement.ClassNameProperty, "CustomListClass", PropertyConditionFlags.IgnoreCase);
AutomationElement targetElement = window.FindFirst(TreeScope.Children, xEllist2);
在进一步考虑之后,我尝试获取所有列名:
AutomationElementCollection headerLines = headerEl.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.HeaderItem));
string headertest = headerLines[0].GetCurrentPropertyValue(AutomationElement.NameProperty) as string;
textBox2.AppendText("Header 1: " + headertest + Environment.NewLine);
不幸的是,在调试模式下,“headerLines”中的元素计数为 0,因此程序会引发错误。
编辑 2:感谢下面的答案 - 我安装了非托管 UI 自动化,它比默认 UIA 拥有更好的可能性。http://uiacomwrapper.codeplex.com/ 如何使用遗留模式从未知控件类型中获取数据?
if((bool)datagrid.GetCurrentPropertyValue(AutomationElementIdentifiers.IsLegacyIAccessiblePatternAvailableProperty))
{
var pattern = ((LegacyIAccessiblePattern)datagrid.GetCurrentPattern(LegacyIAccessiblePattern.Pattern));
var state = pattern.Current.State;
}
编辑 3. IUIAutoamtion 方法(目前不工作)
_automation = new CUIAutomation();
cacheRequest = _automation.CreateCacheRequest();
cacheRequest.AddPattern(UiaConstants.UIA_LegacyIAccessiblePatternId);
cacheRequest.AddProperty(UiaConstants.UIA_LegacyIAccessibleNamePropertyId);
cacheRequest.TreeFilter = _automation.ContentViewCondition;
trueCondition = _automation.CreateTrueCondition();
Process[] ps = Process.GetProcessesByName("program");
IntPtr hwnd = ps[0].MainWindowHandle;
IUIAutomationElement elementMailAppWindow = _automation.ElementFromHandle(hwnd);
List<IntPtr> ls = new List<IntPtr>();
ls = GetChildWindows(hwnd);
foreach (var child in ls)
{
IUIAutomationElement iuiae = _automation.ElementFromHandle(child);
if (iuiae.CurrentClassName == "CustomListClass")
{
var outerArayOfStuff = iuiae.FindAllBuildCache(interop.UIAutomationCore.TreeScope.TreeScope_Children, trueCondition, cacheRequest.Clone());
var outerArayOfStuff2 = iuiae.FindAll(interop.UIAutomationCore.TreeScope.TreeScope_Children, trueCondition);
var countOuter = outerArayOfStuff.Length;
var countOuter2 = outerArayOfStuff2.Length;
var uiAutomationElement = outerArayOfStuff.GetElement(0); // error
var uiAutomationElement2 = outerArayOfStuff2.GetElement(0); // error
//...
//I've erased what's followed next because the code isn't working even now..
}
}
由于这个问题,代码得以实现:
使用 C# 从另一个应用程序的 SysListView32 中的数据网格中读取单元格项
作为结果:
- countOuter 和 countOuter2 长度 = 0
- 无法选择元素(列表中的行)
- 不可能获得任何价值
- 没有任何工作