代码之家  ›  专栏  ›  技术社区  ›  Touhid Mangal

WPF中的脱机图像缓存

  •  0
  • Touhid Mangal  · 技术社区  · 6 年前

    我有一个WPF应用程序 从URL加载图像 当有互联网连接时& 应该从缓存中加载这些图像 当没有活动的internet连接时。

    我的 问题 如果没有任何活动的internet连接,则不会缓存图像以在随后的应用程序启动中显示。

    我已经找了几个小时,几乎所有可能的组合 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 当然是密码。

    有没有可能达到我的目的?如果是,请怎么做?

    编辑: 我的问题不完全是 this SO post ,如@Wilson的注释所示-因为每次下载图像在我的用例中是不同的,但是 the accepted answer's mentioned CachedImage library 已经部分解决了这个问题。

    我换了 Image 阻止 the library's 此用户界面元素:

    <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的direct builds在离线图像缓存中运行良好,但生成的安装文件(使用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()
    

    我已经发了 an issue regarding this crash in library's issue-board .

    1 回复  |  直到 6 年前
        1
  •  0
  •   Touhid Mangal    6 年前

    使用 CachedImage library 已达到标准,如 this SO answer .

    我换了 Image 使用库的this 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脚本中。现在一切都很好。