Windows Community Toolkit 包含一个 ImageEx 控件,可用于管理远程图像的本地缓存和 UI 中图像的异步加载。
作为他们如何实现图像下载的副作用,我们可以访问它使用的静态 HttpClient 实例,并使用您的 API 可能需要的身份验证或其他标头设置 DefaultRequestHeaders。
如果您的所有图像都托管在同一个经过身份验证的服务器上,则此解决方案有效,该工具包是开源的,因此您可以下载源代码并根据自己的需要更改实现。
ImageEx 控件在加载图像时管理可见状态,默认情况下带有漂亮的淡入淡出动画,但是您可以覆盖它,甚至提供PlaceHolder 图像或文本。
- 一种高级方案是使用
PlaceHolder 首先渲染可能被积极缓存的图像的低分辨率版本。这超出了本文的范围,但强调了此解决方案的可扩展性。
魔术发生在这个控件使用的ImageCache内部,我们可以通过将EnableLazyLoading和IsCacheEnabled属性都设置为True来强制使用ImageCache,只要我们之前设置了请求头图片加载完毕后,我们可以直接将Source绑定到外部URL来访问文件。
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
<controls.ImageEx Width="50"
Height="50"
Stretch="UniformToFill"
HorizontalAlignment="Center"
VerticalAlignment="Center"
EnableLazyLoading="True"
IsCacheEnabled="True"
Source="{Binding ImageUrl}" />
此行为未明确记录,通过使用反射访问内部 HttpClient,我们接受在未来版本中可能无法正常工作的风险。
理想情况下,由于 ImageCache.Instance 是静态成员,我们只需要在用户登录时设置 Auth 头,以下代码显示了如何使用任意头来做到这一点:
// set the auth header on the Image Cache!
var httpClient = ImageCache.Instance
.GetType()
.GetProperty("HttpClient", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.NonPublic)
.GetValue(ImageCache.Instance)
as System.Net.Http.HttpClient;
Runtime.ConfigureHttpClient(httpClient);
httpClient.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "---MyUserAuthToken---");
httpClient.DefaultRequestHeaders.Add("My-Token", "---arbitrary token---");
运行时性能很好,但你可以配置ImageCache在内存中保留一些图像,或者我们可以显式或预先加载图像:
在下文中,假设item 是一个数据对象,它具有一个ImageUrl,其中包含一个需要身份验证的资源的URL。
// Define max memory cache size
ImageCache.Instance.MaxMemoryCacheCount = 200;
// Precache data and save it in memory
await ImageCache.Instance.PreCacheAsync(new Uri(item.ImageUrl), Path.GetFileName(item.Thumbnail), true);
// Precache data and save it in on local hard drive
await ImageCache.Instance.PreCacheAsync(new Uri(item.ImageUrl), Path.GetFileName(item.Thumbnail), false);
// Clear cache
await ImageCache.Instance.ClearAsync();