c# - WPF 中的脱机图像缓存
问题描述
我有一个 WPF 应用程序,它在有互联网连接时从 URL 加载图像,并且只要没有活动的互联网连接,就应该从缓存中加载这些图像。
我的问题是 - 在没有任何活动的互联网连接的情况下,图像不会被缓存以显示在后续的应用程序启动中。
我已经搜索了几个小时并尝试了几乎所有可能的CreateOptions
&组合CacheOption
,但结果相同。
XAML 代码如下所示:
<Image
Width="{Binding MY_TILE_W}" MaxWidth="380"
Height="{Binding MY_TILE_H}" MaxHeight="240"
Stretch="UniformToFill">
<Image.CacheMode>
<BitmapCache EnableClearType="False"
RenderAtScale="1"
SnapsToDevicePixels="False" />
</Image.CacheMode>
<Image.Source>
<BitmapImage UriSource="{Binding ImageUrl}"
CreateOptions="IgnoreImageCache"
CacheOption="OnLoad"/>
</Image.Source>
</Image>
没有更多C#
的代码,当然除了Binding
代码。
是否有可能实现我正在尝试的目标?如果是,请问如何?
编辑:我的问题与此 SO 帖子 并不完全相同,如@Wilson 的评论中所示 - 因为在我的用例中每次下载图像都不同,但接受的答案 提到的 CachedImage 库已部分解决了该问题。
我用库的这个 ui 元素替换了Image
块:
<cachedImage:Image Grid.Row="0" Grid.ColumnSpan="2"
Width="{Binding MY_TILE_W}" MaxWidth="380"
Height="{Binding MY_TILE_H}" MaxHeight="240"
Stretch="UniformToFill"
ImageUrl="{Binding ImageUrl}"/>
然后从 VS 2017 直接构建与离线图像缓存一起工作正常,但生成的安装文件(使用 Inno-setup)因以下日志而崩溃:
Set property 'System.Windows.Controls.ItemsControl.ItemTemplate' threw an exception.
Stack Trace: at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
at MyApp.MyWindow.InitializeComponent() in E:\w_Development\DotNet\MyApp\MyWindow.xaml:line 1
at MyApp.MyWindow..ctor(Window window) in E:\w_Development\DotNet\MyApp\MyWindow.xaml.cs:line 54
at MyApp.MainWindow.<NavigateWithDelay>d__3.MoveNext() in E:\w_Development\DotNet\MyApp\MainWindow.xaml.cs:line 35
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.<ThrowAsync>b__6_0(Object state)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at MyApp.App.Main()
解决方案
使用CachedImage 库已经达到了标准,如this SO answer中所示。
我用Image
库的这个 ui 元素替换了块:
<cachedImage:Image Grid.Row="0" Grid.ColumnSpan="2"
Width="{Binding MY_TILE_W}" MaxWidth="380"
Height="{Binding MY_TILE_H}" MaxHeight="240"
Stretch="UniformToFill"
ImageUrl="{Binding ImageUrl}"/>
然后在使用 InnoSetup 脚本生成安装文件后出现异常,因为没有DLL reference
在我的 InnoSetup 脚本中添加。现在一切都很好。
推荐阅读
- ftp - Spring Integration : get poll expression from database
- ios - google maps route between 2 points with multi waypoints swift ios
- go - How to iterate recursively through map[string]interface{}
- php - simplexml_load_string() 在解析这个 Soap xml 时期望参数 1 是字符串
- pacemaker - corosync/pacemaker 将 OCF_RUNNING_MASTER 视为错误
- swift - How to implement both UIViewController stack behaviour
- laravel - how to convert select box html to form html collactive
- python - 导入 settings.py Scrapy
- sql-server - 错误:“SQL Server 未返回响应。连接已关闭。”
- javascript - 为什么我在 JS 中的 focus() 方法不能作为 onfocus 事件处理?