注释
本文档适用于想要使用 System.Windows.Automation 命名空间中定义的托管 UI 自动化类的 .NET Framework 开发人员。 有关 UI 自动化的最新信息,请参阅 Windows 自动化 API:UI 自动化。
本主题介绍 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 指定了以下缓存选项。
要缓存的属性
在激活请求之前,可以通过为每个属性调用 Add(AutomationProperty) 来指定要缓存的属性。
要缓存的控件模式
在激活请求之前,可以逐个调用 Add(AutomationPattern) 来指定要缓存的控制模式。 当一个模式被缓存时,其属性不会自动被缓存;您必须使用 CacheRequest.Add 指定您想要缓存的属性 CacheRequest.Add。
缓存的范围和筛选
可以通过在激活请求之前设置 CacheRequest.TreeScope 属性来指定要缓存其属性和模式的元素。 请求处于活动状态时,范围与检索的元素有关。 例如,如果仅设置Children,然后检索AutomationElement,那么该元素的子元素的属性和模式会被缓存,但该元素本身的属性和模式不会被缓存。 为了确保对检索到的元素本身执行缓存,必须在 Element 属性中包含 TreeScope。 无法将范围设置为Parent或Ancestors。 尽管如此,当子元素被缓存时,父元素也可以被缓存。 有关详细信息,请参阅检索缓存的子元素和父元素。
缓存的范围也会受到 CacheRequest.TreeFilter 属性的影响。 默认情况下,仅对 UI 自动化树控件视图中显示的元素执行缓存。 但是,可以更改此属性以将缓存应用于所有元素,或仅应用于内容视图中显示的元素。
元素引用的强度
检索AutomationElement时,默认情况下,可以访问该元素的所有属性和模式,包括那些未缓存的属性和模式。 但是,为了提高效率,可以通过将AutomationElementMode的CacheRequest属性设置为None,来指定对元素的引用仅引用缓存的数据。 在这种情况下,你无权访问检索到的元素的任何非缓存属性和模式。 这意味着您不能通过 GetCurrentPropertyValue 或 Current
属性访问 AutomationElement 或任何控件模式的任何属性;也不能通过使用 GetCurrentPattern 或 TryGetCurrentPattern 来检索模式。 在缓存模式上,可以调用检索数组属性的方法,例如 SelectionPattern.SelectionPatternInformation.GetSelection,但不调用对控件执行作的任何方法,例如 InvokePattern.Invoke。
一种可能不需要完全引用对象的应用程序的示例是屏幕阅读器,它会预先提取窗口中元素的 Name 和 ControlType 属性,但不需要 AutomationElement 对象本身。
激活缓存请求
仅当在 AutomationElement 对于当前线程处于活动状态的情况下检索 CacheRequest 对象时,才会执行缓存。 有两种方法可以激活 CacheRequest。
通常的方法是调用 Activate。 此方法返回实现 IDisposable的对象。 只要对象存在, IDisposable 请求就保持活动状态。 控制对象生命周期的最简单方法是将调用括在using
(C#)或Using
(Visual Basic)块中。 这样即使引发异常也能确保请求从堆栈中弹出。
如果要嵌套缓存请求,另一种方法是调用 Push。 这会将请求置于堆栈上并激活它。 请求保持活动状态,直到从堆栈中删除。Pop 如果另一个请求被推送到堆栈上,请求将暂时处于非活动状态;只有堆栈上的最高请求处于活动状态。
检索缓存的属性
可以通过以下方法和属性检索元素的缓存属性。
如果请求的属性不在缓存中,则会引发异常。
Cached 像 Current,都以结构成员的方式公开各项属性。 但是,无需检索此结构;可以直接访问各个属性。 例如,可以获取 Name 属性来自 element.Cached.Name
,其中 element
是一个 AutomationElement。
检索缓存的控制模式
可以通过以下方法检索元素的缓存控件模式。
如果模式不在缓存中, GetCachedPattern 则引发异常并 TryGetCachedPattern 返回 false
。
可以通过模式对象的 Cached
属性来检索控件模式的缓存属性。 还可以通过 Current
属性检索当前值,但前提是检索 None 时未指定 AutomationElement。 (Full 是默认值,这允许访问当前值。
检索缓存的子项和父项
当你检索AutomationElement并且通过请求的TreeScope属性为该元素的子元素请求缓存时,之后可以从检索到的元素的CachedChildren属性获取这些子元素。
如果 Element 包含在缓存请求的范围中,则请求的根元素随后可从 CachedParent 任何子元素的属性获取。
注释
无法缓存请求根元素的父项或上级。
更新缓存
只要 UI 中没有任何更改,缓存才有效。 应用程序负责更新缓存,通常是为了响应事件。
如果在 CacheRequest 处于活动状态时订阅事件,则每次调用事件处理程序委托时都会获得一个使用更新的缓存作为事件源的 AutomationElement 。 还可以通过调用 GetUpdatedCache来更新元素的缓存信息。 可以传入原始 CacheRequest 版本以更新以前缓存的所有信息。
更新缓存不会更改任何现有 AutomationElement 引用的属性。