更新:2007 年 11 月
本主题介绍 UI 自动化属性和控件模式的缓存。
在 UI 自动化中,缓存意味着预获取数据。然后,无需进一步的跨进程通信即可访问数据。UI 自动化客户端应用程序通常使用缓存来批量检索属性和控件模式。然后,根据需要从缓存中检索信息。应用程序会定期更新缓存,通常在发生表明 用户界面 (UI) 中的内容发生更改的事件时进行更新。
对于具有服务器端 UI 自动化提供程序的 Windows Presentation Foundation (WPF) 控件和自定义控件,缓存的优势非常突出。在访问客户端提供程序(比如 Win32 控件的默认提供程序)时,其优势稍小一些。
当应用程序激活 CacheRequest 然后使用返回 AutomationElement 的任何方法或属性时,就会进行缓存;例如,FindFirst 和 FindAll。TreeWalker 类的方法例外;只有在将 CacheRequest 指定为参数(例如,TreeWalker.GetFirstChild(AutomationElement, CacheRequest))时,才会进行缓存。
如果在 CacheRequest 处于活动状态时订阅事件,也会进行缓存。作为事件来源传递到事件处理程序的 AutomationElement 包含由原始 CacheRequest 指定的缓存属性和模式。在订阅事件后对 CacheRequest 进行的任何更改没有影响。
可以对元素的 UI 自动化属性和控件模式进行缓存。
本主题包括下列各节。
- 缓存选项
- 激活 CacheRequest
- 检索缓存的属性
- 检索缓存的控件模式
- 检索缓存的子项和父项
- 更新缓存
- 相关主题
缓存选项
CacheRequest 指定以下缓存选项。
要缓存的属性
可以通过在激活请求之前为每个属性调用 Add(AutomationProperty) 来指定要缓存的属性。
要缓存的控件模式
可以通过在激活请求之前为每个模式调用 Add(AutomationPattern) 来指定要缓存的控件模式。在缓存模式时,不会自动缓存模式的属性;您必须通过使用 CacheRequest.Add 来指定要缓存的属性。
缓存的范围和筛选
可以通过在激活请求之前设置 CacheRequest.TreeScope 属性来指定要缓存其属性和模式的元素。范围与请求处于活动状态时检索的元素有关。例如,如果只设置 Children 然后检索 AutomationElement,则会缓存该元素的子项的属性和模式,但不会缓存该元素本身的属性和模式。若要确保对检索的元素本身进行缓存,您必须在 TreeScope 属性中包括 Element。无法将范围设置为 Parent 或 Ancestors。不过,在缓存了子元素后,就可以缓存父元素;请参见本主题中的“检索缓存的子项和父项”。
缓存的范围还受 CacheRequest.TreeFilter 属性的影响。默认情况下,只会对出现在 UI 自动化树的控件视图中的元素执行缓存。但是,可以更改此属性以将缓存应用于所有元素,或者只应用于出现在内容视图中的元素。
元素引用的强度
在检索 AutomationElement 时,默认情况下您可以访问该元素的所有属性和模式,包括那些未缓存的属性和模式。不过,为了提高效率,您可以通过将 CacheRequest 的 AutomationElementMode 属性设置为 None 来指定元素引用只引用缓存的数据。在这种情况下,您无法访问所检索元素的任何未缓存属性和模式。这意味着,您无法通过 GetCurrentPropertyValue 或者 AutomationElement 的 Current 属性或任何控件模式访问任何属性;也无法通过使用 GetCurrentPattern 或 TryGetCurrentPattern 检索模式。在缓存的模式上,您可以调用检索数组属性的方法(如 SelectionPattern.SelectionPatternInformation.GetSelection),但不能调用对控件执行操作的任何方法(如 InvokePattern.Invoke)。
可能无需完全引用对象的应用程序的一个示例是屏幕阅读器,它将预提取窗口中元素的 Name 和 ControlType 属性,但不需要 AutomationElement 对象本身。
激活 CacheRequest
只有当在 CacheRequest 对于当前线程处于活动状态的情况下检索 AutomationElement 对象时,才会执行缓存。有两种方法可激活 CacheRequest。
通常的方法是调用 Activate。此方法返回实现 IDisposable 的对象。只要 IDisposable 对象存在,请求就将保持活动状态。控制对象生存期最简单的方法是将调用包括在 using (C#) 或 Using (Visual Basic) 块中。这样即使引发异常也能确保请求从堆栈中弹出。
另一种方法(在希望嵌套缓存请求时十分有用)是调用 Push。此方法将请求放在堆栈上,并激活请求。在 Pop 从堆栈中移除请求之前,请求将保持活动状态。如果将另一个请求推入堆栈,该请求将暂时变为非活动状态;只有堆栈顶部的请求才会处于活动状态。
检索缓存的属性
您可以通过以下方法和属性检索元素的缓存属性。
如果请求的属性不在缓存中,将会引发异常。
Cached 像 Current 一样,都以结构成员的方式公开各项属性。不过,您无需检索此结构;您可以直接访问各项属性。例如,可以从 element.Cached.Name 中获取 Name 属性,其中 element 是 AutomationElement。
检索缓存的控件模式
您可以通过以下方法检索元素的缓存控件模式。
如果模式不在缓存中,GetCachedPattern 将引发异常,并且 TryGetCachedPattern 将返回 false。
您可以通过使用模式对象的 Cached 属性来检索控件模式的缓存属性。您还可以通过 Current 属性检索当前值,但只有当检索 AutomationElement 时未指定 None 的情况下才能这样做。(默认值为 Full,并且此值允许访问当前值。)
检索缓存的子项和父项
如果检索 AutomationElement 并通过请求的 TreeScope 属性请求对该元素的子项进行缓存,随后将可以从所检索元素的 CachedChildren 属性中获取子元素。
如果 Element 包括在缓存请求的范围中,随后将可以从任何子元素的 CachedParent 属性中获取请求的根元素。
![]() |
---|
您无法缓存请求根元素的父项或上级。 |
更新缓存
缓存只有在 UI 中没有任何更改时才有效。应用程序负责更新缓存,通常是为了响应事件。
如果在 CacheRequest 处于活动状态时订阅事件,则无论您何时调用事件处理程序委托,都会获得一个使用更新的缓存作为事件源的 AutomationElement。您也可以通过调用 GetUpdatedCache 来更新元素的缓存信息。您可以传入原始 CacheRequest 来更新以前缓存的所有信息。
更新缓存不会更改任何现有 AutomationElement 引用的属性。