在 UI 自动化客户端中缓存

备注

本文档适用于想要使用 System.Windows.Automation 命名空间中定义的托管 UI 自动化类的 .NET Framework 开发人员。 有关 UI 自动化的最新信息,请参阅 Windows 自动化 API:UI 自动化

本主题介绍 UI 自动化属性和控件模式的缓存。

在 UI 自动化中,缓存意味着预提取的数据。 然后,无需进一步的跨进程通信即可访问数据。 UI 自动化客户端应用程序通常使用缓存来批量检索属性和控件模式。 然后,根据需要从缓存中检索信息。 应用程序会定期更新缓存,通常使为了响应表明用户界面 (UI) 发生更改的事件。

对于具有服务器端 UI 自动化提供程序的 Windows Presentation Foundation (WPF) 控件和自定义控件,缓存的优势非常突出。 在访问客户端提供程序(如 Win32 控件的默认提供程序)时,其优势稍小一些。

当应用程序激活 CacheRequest ,然后使用任何返回 AutomationElement的方法或属性时,就会进行缓存;例如, FindFirstFindAllTreeWalker 类的方法例外;只有在将 CacheRequest 指定为参数(例如, TreeWalker.GetFirstChild(AutomationElement, CacheRequest))时,才会进行缓存。

如果 CacheRequest 处于活动状态时订阅事件,也会进行缓存。 作为事件来源传递到事件处理程序的 AutomationElement 包含由原始 CacheRequest指定的缓存属性和模式。 在订阅事件后对 CacheRequest 进行的任何更改都没有影响。

可以缓存元素的 UI 自动化属性和控件模式。

缓存选项

CacheRequest 指定以下缓存选项。

要缓存的属性

可以通过在激活请求之前为每个属性调用 Add(AutomationProperty) 来指定要缓存的属性。

要缓存的控件模式

可以通过在激活请求之前为每个模式调用 Add(AutomationPattern) 来指定要缓存的控件模式。 在缓存模式时,不会自动缓存模式的属性;必须通过使用 CacheRequest.Add指定想要缓存的属性。

缓存的范围和筛选

可以通过在激活请求之前设置 CacheRequest.TreeScope 属性来指定想要缓存其属性和模式的元素。 范围与请求处于活动状态时检索的元素有关。 例如,如果仅设置 Children,然后检索 AutomationElement,则会缓存该元素的子项的属性和模式,但不会缓存该元素本身的属性和模式。 若要确保对检索的元素本身进行缓存,则必须在 Element 属性中包括 TreeScope 。 不可将范围设置为 ParentAncestors。 但是,在缓存子元素时,可以缓存父元素。 有关详细信息,请参阅检索缓存的子元素和父元素

缓存的范围还会受 CacheRequest.TreeFilter 属性的影响。 默认情况下,只会对出现在 UI 自动化树的控件视图中的元素执行缓存。 但是,可以更改此属性以将缓存应用于所有元素,或者只应用于出现在内容视图中的元素。

元素引用的强度

在检索 AutomationElement时,默认情况下可以访问该元素的所有属性和模式,包括那些未缓存的属性和模式。 但是,为了提高效率,可以通过将 AutomationElementModeCacheRequest 属性设置为 None来指定元素引用只引用缓存的数据。 在这种情况下,你没有权限访问所检索元素的任何未缓存属性和模式。 这意味着你无法通过 GetCurrentPropertyValue 或者 CurrentAutomationElement 属性或任何控件模式访问任何属性;也无法通过使用 GetCurrentPatternTryGetCurrentPattern检索模式。 在缓存的模式中,可以调用检索数组属性的方法(如 SelectionPattern.SelectionPatternInformation.GetSelection),但不能调用对控件执行操作的任何方法(如 InvokePattern.Invoke)。

可能无需完全引用对象的应用程序的一个示例是屏幕阅读器,它将预提取窗口中的元素的 NameControlType 属性,但不需要 AutomationElement 对象本身。

激活 CacheRequest

仅当在 AutomationElement 对于当前线程处于活动状态的情况下检索 CacheRequest 对象时,才会执行缓存。 有两种方法可激活 CacheRequest

通常的方法是调用 Activate。 此方法返回实现 IDisposable的对象。 只要 IDisposable 对象存在,请求就将保持活动状态。 控制对象的生存期的最简单方法是将调用括在 using (C#) 或 Using (Visual Basic) 块中。 这样即使引发异常也能确保请求从堆栈中弹出。

另一种方法是调用 Push,此方法在你想要嵌套缓存请求时非常有用。 此方法将请求放在堆栈上,并激活请求。 在 Pop从堆栈中删除请求之前,请求将保持活动状态。 如果将另一个请求推入堆栈,该请求将暂时变为非活动状态;只有堆栈顶部的请求才会处于活动状态。

检索缓存的属性

你可以通过以下方法和属性检索元素的缓存属性。

如果请求的属性不在缓存中,则会引发异常。

CachedCurrent,都以结构成员的方式公开各项属性。 但是,无需检索此结构;你可以直接访问各项属性。 例如,可以从 Name 中获取 element.Cached.Name属性,其中 elementAutomationElement

检索缓存的控件模式

可以通过以下方法检索元素的缓存控件模式。

如果模式不在缓存中,则 GetCachedPattern 会引发异常,并且 TryGetCachedPattern 会返回 false

可以通过使用模式对象的 Cached 属性来检索控件模式的缓存属性。 也可以通过 Current 属性检索当前值,但只有当检索 None 时未指定 AutomationElement 的情况下才能这样做。 (默认值为Full ,并且此值允许访问当前值。)

检索缓存的子项和父项

如果检索 AutomationElement 并通过请求的 TreeScope 属性请求对该元素的子项进行缓存,随后将可以从所检索元素的 CachedChildren 属性中获取子元素。

如果 Element 已包含在缓存请求的范围内,则随后可从任何子元素的 CachedParent 属性中获取请求的根元素。

备注

无法缓存请求根元素的父项或上级。

更新缓存

只要 UI 中没有更改,缓存就有效。 应用程序负责更新缓存,通常是为了响应事件。

如果在 CacheRequest 处于活动状态时订阅事件,则每次调用事件处理程序委托时都会获得一个使用更新的缓存作为事件源的 AutomationElement 。 还可以通过调用 GetUpdatedCache来更新元素的缓存信息。 可以传入原始 CacheRequest 来更新以前缓存的所有信息。

更新缓存不会更改任何现有 AutomationElement 引用的属性。

请参阅