Public Class MyImage Inherits Image Private FileCacheExpiredTime As TimeSpan = New TimeSpan(7, 0, 0, 0) ' 一个星期的缓存有效期 ''' ''' 是否使用缓存 ''' ''' Public Property UseCache As Boolean Get Return GetValue(UseCacheProperty) End Get Set(value As Boolean) SetValue(UseCacheProperty, value) End Set End Property Public Shared ReadOnly UseCacheProperty As DependencyProperty = DependencyProperty.Register("UseCache", GetType(Boolean), GetType(MyImage), New PropertyMetadata(True)) Private _SourceData As String = "" ''' ''' 重写Image的Source属性 ''' Public Shadows Property Source As String Get Return _SourceData End Get Set(value As String) If String.IsNullOrEmpty(value) Then Exit Property _SourceData = value Try If Not value.StartsWithF("http") Then ' 本地资源直接使用 MyBase.Source = New MyBitmap(_SourceData) Exit Property End If Dim NeedDownload As Boolean = True '是否需要下载/本地是否有有效缓存 Dim TempFilePath As String = PathTemp & "Cache\MyImage\" & GetHash(_SourceData) & ".png" If UseCache AndAlso File.Exists(TempFilePath) AndAlso (DateTime.Now - File.GetCreationTime(TempFilePath)) < FileCacheExpiredTime Then NeedDownload = False ' 缓存文件存在且未过期,不需要重下 If Not NeedDownload Then MyBase.Source = New MyBitmap(TempFilePath) Exit Property End If If File.Exists(TempFilePath) Then '先显示着旧图片,下载新图片 Rename(TempFilePath, TempFilePath & ".old") MyBase.Source = New MyBitmap(TempFilePath & ".old") End If ' 开一个线程下载在线图片 RunInNewThread(Sub() PicLoader(_SourceData, TempFilePath), "MyImage PicLoader " & GetUuid() & "#", ThreadPriority.BelowNormal) Catch ex As Exception Log(ex, "加载图片失败") End Try End Set End Property Public Shared Shadows ReadOnly SourceProperty As DependencyProperty = DependencyProperty.Register("Source", GetType(String), GetType(MyImage), New PropertyMetadata(New PropertyChangedCallback( Sub(sender As DependencyObject, e As DependencyPropertyChangedEventArgs) If Not IsNothing(sender) Then If String.IsNullOrEmpty(e.NewValue.ToString()) Then Exit Sub CType(sender, MyImage).Source = e.NewValue.ToString() End If End Sub))) Private Sub PicLoader(FileUrl As String, TempFilePath As String) Dim Retried As Boolean = False RetryStart: Try Dim UnCompleteFile As String = TempFilePath & ".dl" '加一个下载中的后缀,防止中途关闭程序下载中断但是没下完,从而导致第二次显示的是损坏的图片…… NetDownload(FileUrl, UnCompleteFile) Rename(UnCompleteFile, TempFilePath) RunInUi(Sub() MyBase.Source = New MyBitmap(TempFilePath) End Sub) File.Delete(TempFilePath & ".old") Catch ex As Exception If Not Retried Then Retried = True GoTo RetryStart Else Log(ex, $"[MyImage] 下载图片失败") End If End Try End Sub End Class