MyImage.vb 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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 _DownloadTask As Task
  8. Private FileCacheExpiredTime As TimeSpan = New TimeSpan(7, 0, 0, 0) ' 一个星期的缓存有效期
  9. Public Property UseCache As Boolean
  10. Get
  11. Return _UseCache
  12. End Get
  13. Set(value As Boolean)
  14. _UseCache = value
  15. End Set
  16. End Property
  17. ''' <summary>
  18. ''' 重写Image的Source属性
  19. ''' </summary>
  20. Public Shadows Property Source As String
  21. Get
  22. Return _SourceData
  23. End Get
  24. Set(value As String)
  25. If String.IsNullOrEmpty(value) Then Exit Property
  26. _SourceData = value
  27. If Not value.StartsWithF("http") Then ' 本地资源直接使用
  28. MyBase.Source = New MyBitmap(_SourceData)
  29. Exit Property
  30. End If
  31. If _DownloadTask IsNot Nothing AndAlso Not _DownloadTask.IsCompleted Then ' 之前下载任务还在,直接砍了
  32. _DownloadTask.Dispose()
  33. End If
  34. Dim NeedDownload As Boolean = True '是否需要下载/本地是否有有效缓存
  35. Dim TempFilePath As String = PathTemp & "Cache\MyImage\" & GetHash(_SourceData) & ".png"
  36. If _UseCache And File.Exists(TempFilePath) And (DateTime.Now - File.GetCreationTime(TempFilePath)) < FileCacheExpiredTime Then NeedDownload = False ' 缓存文件存在且未过期,不需要重下
  37. If Not NeedDownload Then
  38. MyBase.Source = New MyBitmap(TempFilePath)
  39. Exit Property
  40. End If
  41. ' 异步下载图片
  42. Dim TaskID = 0
  43. _DownloadTask = New Task(Sub()
  44. NetDownload(_SourceData, TempFilePath, True)
  45. End Sub)
  46. TaskID = _DownloadTask.Id
  47. _DownloadTask.Start()
  48. _DownloadTask.ContinueWith(Sub(t)
  49. If t.IsCompleted AndAlso t.Id = TaskID Then ' 任务没有被干掉
  50. MyBase.Source = New MyBitmap(TempFilePath)
  51. End If
  52. End Sub, TaskScheduler.FromCurrentSynchronizationContext())
  53. End Set
  54. End Property
  55. Public Shared Shadows ReadOnly SourceProperty As DependencyProperty = DependencyProperty.Register("Source", GetType(String), GetType(MyImage), New PropertyMetadata(New PropertyChangedCallback(
  56. Sub(sender As DependencyObject, e As DependencyPropertyChangedEventArgs)
  57. If Not IsNothing(sender) Then
  58. If String.IsNullOrEmpty(e.NewValue.ToString()) Then Exit Sub
  59. CType(sender, MyImage).Source = e.NewValue.ToString()
  60. End If
  61. End Sub)))
  62. End Class