Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.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# 注册UIAutomation结构更改事件_C#_Wpf_Events - Fatal编程技术网

C# 注册UIAutomation结构更改事件

C# 注册UIAutomation结构更改事件,c#,wpf,events,C#,Wpf,Events,我正在开发一个应用程序,该应用程序监视给定应用程序的自动化事件。目前,我正在开发一个WPF应用程序,专门处理结构更改事件 public void MonitorStructureChangedEvents(AutomationElement element) { Automation.AddStructureChangedEventHandler(element, TreeScope.Subtree, OnStructureChanged); } 在这种情况下,元素是应用程序(其主窗口

我正在开发一个应用程序,该应用程序监视给定应用程序的自动化事件。目前,我正在开发一个WPF应用程序,专门处理结构更改事件

public void MonitorStructureChangedEvents(AutomationElement element)
{
    Automation.AddStructureChangedEventHandler(element, TreeScope.Subtree, OnStructureChanged);
}
在这种情况下,
元素
是应用程序(其主窗口)的根
自动元素
。所讨论的WPF应用程序只是一个带有网格视图和各种控件(文本框、复选框、按钮等)的
窗口。这是我专门为测试UIAutomation事件而开发的测试应用程序

我使用一个单元测试项目来测试这些事件,并使用
ClassInitialize
方法启动应用程序。我不会注册
StructureChanged
事件,直到应用程序启动并且我通过WMI在我的
TestMethod
中找到它。应用程序作为新进程生成

但是,在注册structure changed events时,我会收到应用程序主窗口中所有元素的structure changed events,即使WPF应用程序实际上处于空闲状态。我在主窗口中有一些按钮,用于添加和删除控件以测试
StructureChanged
事件,它确实有效,但是我不确定为什么在最初注册时,所有元素都会触发一个StructureChanged事件

编辑:在进一步测试之后,我注意到,只要我单击应用程序窗口或将鼠标悬停在按钮上,就会触发这些事件。然后,它为应用程序中的每个元素触发一次结构更改事件。完成后,如果我将鼠标悬停在按钮上或单击应用程序(即使在单击另一个应用程序或桌面后),它也不再触发结构更改事件


Edit2:经过进一步测试,我相信我找到了问题的原因,但还没有解决方案。当我尝试
TreeWalker.RawViewWalker.GetFirstChild(rootApplicationElement)
时,我收到一个空值。我正在获取的
AutomationElement
似乎没有缓存子项。一旦我在元素上添加了
StructureChanged
事件处理程序,
TreeWalker
方法就工作了,我得到了一个有效的元素。当我在这之后激活窗口时,它就会意识到它现在有了所有这些新的子元素。是否有一种方法可以缓存
rootApplicationElement
的所有后代,以便在添加事件处理程序之前,我可以遍历整个子树?

我可以使用以下方法解决此问题

CacheRequest request = new CacheRequest();
request.TreeScope = TreeScope.Element | TreeScope.Descendants;
using (request.Activate())
{
    rootApplicationElement = AutomationElement.RootElement.FindAll(TreeScope.Children,
           new PropertyCondition(AutomationElementIdentifiers.ProcessIdProperty, ApplicationInstance.ProcessId))[0];
}
我不建议人们以这种方式获取根元素,因为如果一个应用程序有多个窗口,您将获得多个结果,但这是根据特定的测试需要定制的