У меня есть приложение 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 частично решила проблему.
Я заменил блок 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}"/>
Затем прямые сборки из 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()
Я выложил проблема, связанная с этим сбоем на доске задач библиотеки.
Возможный дубликат Как кэшировать изображения на клиенте для приложения WPF?





Использование Библиотека CachedImage соответствует критериям, как указано в этот ТАК ответ.
Я заменил блок 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. Теперь все работает нормально.
@Clemens, не могли бы вы дать более подробную информацию - например, фрагмент, алгоритм или ссылку на такую реализацию?