UI Automation不适用于DataGridView [英] UI Automation not working for DataGridView

查看:1574
本文介绍了UI Automation不适用于DataGridView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在尝试了几个解决方案之后,我迫切需要帮助。

After trying out several solutions, I am in desperate need for help.

我尝试了几种方法,最后复制并仍然停留在使用UIAutomation获取Datagrid的完整内容

I tried several approaches, before finally copying and still being stuck with the solution from Getting full contents of a Datagrid using UIAutomation.

我们来谈谈代码,请考虑以下意见:

Let's talk code, please consider the comments:

// 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;
    }

}

我无法获取 GridPattern ,也不能从 datagrid 中的 TablePattern 实例,例外:

I can neither fetch a GridPattern, nor a TablePattern instance from datagrid, both results in an exception:

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客户端的常规用户权限和提升的管理员权限,这两者都产生了与此相同的结果。

I am compiling to .Net Framework 4.5. Tried both regular user rights and elevated admin rights for the UI Automation client, both yielded the same results described here.

为什么 DataGridView return 0 rows?

Why does the DataGridView return 0 rows?

为什么我无法获得其中一种模式?

Why can't I get one of the patterns?

为了帮助我,Kudos!

Kudos for helping me out!

帮助没有为我的窍门。以下代码很难返回所有行(包括头文件):

James help didn't to the trick for me. The following code tough returns all rows (including the headers):

var rows = dataGrid.FindAll(TreeScope.Children, PropertyCondition.TrueCondition);

然后可以通过他们的 ControlType ControlType.Header

Header cells can then be identified by their ControlType of ControlType.Header.

推荐答案

您正在复制的代码有缺陷我刚刚通过此示例程序对您的上面的代码,它的工作原理。

The code that you are copying is flawed. I just tested this scenario with an adaptation of this sample program factoring in your code above, and it works.

主要区别在于上面的代码是使用 TreeScope.Children 来获取datagrid元素。这个选项只能抓住父代的直接子代,所以如果你的datagrid是嵌套的,那么它不会工作。更改它使用 TreeScope.Descendants ,它应该按预期工作。

The key difference is that the code above is using TreeScope.Children to grab the datagrid element. This option only grabs immediate children of the parent, so if your datagrid is nested it's not going to work. Change it to use TreeScope.Descendants, and it should work as expected.

var datagrid = bw.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "dgvControlProperties"));

这是一个链接各种Treescope选项的行为。另外,我不知道如何将这些行绑定到网格中,但是在我的测试场景中我已经这样做了,并且它完美无缺地运行。

Here is a link to how the various Treescope options behave. Also, I don't know how your binding the rows to the grid, but I did it like this in my test scenario and it worked flawlessly.

希望这有帮助。

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;

这篇关于UI Automation不适用于DataGridView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆