在尝试了几种解决方案后,我迫切需要帮助。
我尝试了几种方法,在最终复制之前仍然坚持使用 Getting full contents of a Datagrid using UIAutomation 中的解决方案.
让我们谈谈代码,请考虑评论:
// Get Process ID for desired window handle
uint processID = 0;
GetWindowThreadProcessId(hwnd, out processID);
var desktop = AutomationElement.RootElement;
// Find AutomationElement for the App's window
var bw = AutomationElement.RootElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ProcessIdProperty, (int)processID));
// Find the DataGridView in question
var datagrid = bw.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "dgvControlProperties"));
// Find all rows from the DataGridView
var loginLines = datagrid.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.DataItem));
// Badumm Tzzz: loginLines has 0 items, foreach is therefore not executed once
foreach (AutomationElement loginLine in loginLines)
{
var loginLinesDetails = loginLine.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Custom));
for (var i = 0; i < loginLinesDetails.Count; i++)
{
var cacheRequest = new CacheRequest
{
AutomationElementMode = AutomationElementMode.None,
TreeFilter = Automation.RawViewCondition
};
cacheRequest.Add(AutomationElement.NameProperty);
cacheRequest.Add(AutomationElement.AutomationIdProperty);
cacheRequest.Push();
var targetText = loginLinesDetails[i].FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "TextBlock"));
cacheRequest.Pop();
var myString = targetText.Cached.Name;
}
}
我既无法从 datagrid
获取 GridPattern
实例,也无法获取 TablePattern
实例,两者都会导致异常:
GridPattern gridPattern = null;
try
{
gridPattern = datagrid.GetCurrentPattern(GridPattern.Pattern) as GridPattern;
}
catch (InvalidOperationException ex)
{
// It fails!
}
TablePattern tablePattern = null;
try
{
tablePattern = datagrid.GetCurrentPattern(TablePattern.Pattern) as TablePattern;
}
catch (InvalidOperationException ex)
{
// It fails!
}
预先将行添加到 DataGridView
,如下所示:
dgvControlProperties.Rows.Add(new object[] { false, "Some Text", "Some other text" });
我正在编译为 .Net Framework 4.5。尝试了 UI Automation 客户端的常规用户权限和提升的管理员权限,两者都产生了此处描述的相同结果。
为什么 DataGridView
返回 0 行?
为什么我无法获得其中一种模式?
感谢您帮助我!
更新:
James 的帮助对我没用。以下代码会返回所有行(包括标题):
var rows = dataGrid.FindAll(TreeScope.Children, PropertyCondition.TrueCondition);
然后可以通过 ControlType.Header
的 ControlType
来识别标题单元格。
最佳答案
您复制的代码有缺陷。我刚刚用 this sample program 的改编测试了这个场景考虑到您上面的代码,它可以工作。
主要区别在于上面的代码使用 TreeScope.Children
来获取数据网格元素。此选项仅抓取父项的直接子项,因此如果您的数据网格是嵌套的,它将无法工作。将其更改为使用 TreeScope.Descendants
,它应该会按预期工作。
var datagrid = bw.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "dgvControlProperties"));
Here is a link了解各种 Treescope 选项的行为方式。另外,我不知道你是如何将行绑定(bind)到网格的,但我在我的测试场景中是这样做的,而且它工作得很好。
希望这对您有所帮助。
public class DataObject
{
public string FieldA { get; set; }
public string FieldB { get; set; }
public string FieldC { get; set; }
}
List<DataObject> items = new List<DataObject>();
items.Add(new DataObject() {FieldA="foobar",FieldB="foobar",FieldC="foobar"});
items.Add(new DataObject() { FieldA = "foobar", FieldB = "foobar", FieldC = "foobar" });
items.Add(new DataObject() { FieldA = "foobar", FieldB = "foobar", FieldC = "foobar" });
dg.ItemsSource = items;
关于c# - UI 自动化不适用于 DataGridView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19511546/