MyImage.vb 4.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. Imports System.Threading.Tasks
  2. Public Class MyImage
  3. Inherits Image
  4. '事件
  5. Private _SourceData As String = ""
  6. Private _UseCache As Boolean = False
  7. Private FileCacheExpiredTime As TimeSpan = New TimeSpan(7, 0, 0, 0) ' 一个星期的缓存有效期
  8. Public Property UseCache As Boolean
  9. Get
  10. Return _UseCache
  11. End Get
  12. Set(value As Boolean)
  13. _UseCache = value
  14. End Set
  15. End Property
  16. ''' <summary>
  17. ''' 重写Image的Source属性
  18. ''' </summary>
  19. Public Shadows Property Source As String
  20. Get
  21. Return _SourceData
  22. End Get
  23. Set(value As String)
  24. If String.IsNullOrEmpty(value) Then Exit Property
  25. _SourceData = value
  26. Try
  27. If Not value.StartsWithF("http") Then ' 本地资源直接使用
  28. MyBase.Source = New MyBitmap(_SourceData)
  29. Exit Property
  30. End If
  31. Dim NeedDownload As Boolean = True '是否需要下载/本地是否有有效缓存
  32. Dim TempFilePath As String = PathTemp & "Cache\MyImage\" & GetHash(_SourceData) & ".png"
  33. If _UseCache And File.Exists(TempFilePath) And (DateTime.Now - File.GetCreationTime(TempFilePath)) < FileCacheExpiredTime Then NeedDownload = False ' 缓存文件存在且未过期,不需要重下
  34. If Not NeedDownload Then
  35. MyBase.Source = New MyBitmap(TempFilePath)
  36. Exit Property
  37. End If
  38. ' 开一个线程处理在线图片
  39. RunInNewThread(Sub() PicLoader(_SourceData, TempFilePath), "MyImage PicLoader " & GetUuid() & "#", ThreadPriority.BelowNormal)
  40. Catch ex As Exception
  41. Log(ex, "加载图片失败")
  42. End Try
  43. End Set
  44. End Property
  45. Public Shared Shadows ReadOnly SourceProperty As DependencyProperty = DependencyProperty.Register("Source", GetType(String), GetType(MyImage), New PropertyMetadata(New PropertyChangedCallback(
  46. Sub(sender As DependencyObject, e As DependencyPropertyChangedEventArgs)
  47. If Not IsNothing(sender) Then
  48. If String.IsNullOrEmpty(e.NewValue.ToString()) Then Exit Sub
  49. CType(sender, MyImage).Source = e.NewValue.ToString()
  50. End If
  51. End Sub)))
  52. Private Sub PicLoader(FileUrl As String, TempFilePath As String)
  53. Dim Retried As Boolean = False
  54. RetryStart:
  55. Try
  56. If File.Exists(TempFilePath) Then '先显示着旧图片,下载新图片
  57. Rename(TempFilePath, TempFilePath & ".old")
  58. RunInUi(Sub()
  59. MyBase.Source = New MyBitmap(TempFilePath & ".old")
  60. End Sub)
  61. End If
  62. NetDownload(FileUrl, TempFilePath)
  63. RunInUi(Sub()
  64. MyBase.Source = New MyBitmap(TempFilePath)
  65. End Sub)
  66. File.Delete(TempFilePath & ".old")
  67. Catch ex As Exception
  68. If Not Retried Then
  69. Retried = True
  70. GoTo RetryStart
  71. Else
  72. Log(ex, $"[MyImage] 下载图片失败")
  73. RunInUi(Sub() MyBase.Source = New MyBitmap(PathImage & "Icons/NoIcon.png"))
  74. End If
  75. End Try
  76. End Sub
  77. End Class