Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# TreeWalker从另一个窗口遍历控件_C#_Ui Automation_Automationelement - Fatal编程技术网

C# TreeWalker从另一个窗口遍历控件

C# TreeWalker从另一个窗口遍历控件,c#,ui-automation,automationelement,C#,Ui Automation,Automationelement,我正在使用包含大量日志消息的应用程序窗口。我需要过滤它们并检索那些只符合某些条件的。我选择遍历它们都是TreeWalker,因为在AutomationElement.GetAll()之后过滤大量的消息太昂贵了(可能有数千条消息) List messages=newlist(); TreeWalker=new TreeWalker(新属性条件(AutomationElement.ControlTypeProperty,ControlType.DataItem)); AutomationElemen

我正在使用包含大量日志消息的应用程序窗口。我需要过滤它们并检索那些只符合某些条件的。我选择遍历它们都是
TreeWalker
,因为在
AutomationElement.GetAll()
之后过滤大量的消息太昂贵了(可能有数千条消息)

List messages=newlist();
TreeWalker=new TreeWalker(新属性条件(AutomationElement.ControlTypeProperty,ControlType.DataItem));
AutomationElement行=walker.GetFirstChild(parentDatagrid);
while(行!=null)
{
如果(/*某些条件*/)
messages.Add(行);
row=walker.GetNextSibling(row);
}
这是我正在测试的控件层次结构的UISpy视图

意外地,
消息
长度大于实际日志消息计数。我查询了额外的自动化元素UISpy,发现这些元素是从另一个窗口检索到的(它们也符合条件
ControlTypeProperty=ControlType.DataItem
)。此外,此窗口甚至属于另一个应用程序
TreeWalker
完成了在
parentDatagrid
范围内的搜索,并继续遍历所有桌面层次结构


当然,我希望得到datagrid的唯一子元素。什么会导致这种奇怪的
TreeWalker
行为?也许,我的代码是错误的,但我多次编写了相同的片段,并且工作正常。

事实上,我无法告诉您TreeWalker为什么会这样做,因为我从未使用TreeWalker进行导航。我只是用它来查找父母、孩子、西伯利亚人等等

我可以告诉你的是,我有很好的使用以下方面的经验:

List<AutomationElement> messages = new List<AutomationElement>();
AutomationElement parentDatagrid;//your AE

Condition yourCond = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.DataItem));
AutomationElementCollection aECollection;
aECollection= parentDatagrid.FindAll(TreeScope.Element | TreeScope.Descendants, yourCond);
foreach (AutomationElement element in aECollection)
{
    //whatever you like
}
List messages=newlist();
AutomationElement parentDatagrid//你的AE
Condition yourCond=新属性Condition(AutomationElement.ControlTypeProperty,ControlType.DataItem));
自动元素收集;
aECollection=parentDatagrid.FindAll(TreeScope.Element | TreeScope.substands,yourCond);
foreach(aECollection中的AutomationElement元素)
{
//随便你
}
当然,如果性能是一个问题,那么您必须小心使用TreeScope.subjections。然后,你应该考虑TreeScope,而不是孩子,因为后代看所有的子元素和孩子只是在直接的孩子。< / P>
希望这有帮助

当您创建一个自定义的
TreeWalker
时,就像您所做的那样,行为将与您提到的一样。您最好使用
TreeWalker.ControlViewWalker
,然后检查每个检索到的元素是否符合您的条件。

谢谢您的回复。这里特意将TreeWalker用于导航,因为它允许逐个遍历控件,而无需像AutomationElement.FindAll()那样预加载所有控件。只是为了确保:您是否也使用TreeScope.Children而不是TreeScope.subjections尝试过它?我测试了一个示例应用程序,有一些层次结构(大约30个),总共大约250个元素,每个元素用TreeScope大约需要0,3-0,6秒。如果您正在自动化wpf控件,则速度要快得多(大约0,01-0001),否则我很抱歉。。。下面的示例显示了从列表中检索指定项的两种方法,一种使用TeeWalk,另一种使用FinDALL。第一种技术对于Win32控件来说往往更快,但第二种对于Windows演示基础(WPF)控件来说更快。
List<AutomationElement> messages = new List<AutomationElement>();
AutomationElement parentDatagrid;//your AE

Condition yourCond = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.DataItem));
AutomationElementCollection aECollection;
aECollection= parentDatagrid.FindAll(TreeScope.Element | TreeScope.Descendants, yourCond);
foreach (AutomationElement element in aECollection)
{
    //whatever you like
}