WP7 可以在XAML中使用的 缓存图片控件(适合静态)

首先感谢 kiminozo 分享的代码

可以先看下他的这篇博客: 

WP7应用开发笔记 继承BitmapSource并使用独立存储来缓存远程的图片

 

我修改了下使它可以再XAML中使用

像这样

 <Image Margin="5"     Width="{Binding imgWidth}"  DoubleTap="PleasureListImage_DoubleTap"  Stretch="Uniform"    MaxWidth="400"  >
   <Image.Source>
         <StorageCached:StorageCachedImage   UriSource="{Binding imgUrl}"  /> 
   </Image.Source>  
</Image>

 

 

改造后的代码如下:

View Code
  1     /// <summary>
  2     /// 独立存储缓存的图片源
  3     /// </summary>
  4     public sealed class StorageCachedImage : BitmapSource
  5     {
  6         private Uri uriSource;
  7         private string filePath;
  8         //缓存目录
  9         private const string CacheDirectory = StringResources.TEMP_IMAGE_URL;
 10 
 11 
 12         public  DependencyProperty UriSourceProperty ;
 13 
 14         void UriSourcePropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
 15         {
 16             
 17             string s = e.NewValue as string;
 18             if (s != null)
 19             {
 20                 uriSource = new Uri(s, UriKind.Absolute);
 21                 Debug.WriteLine(uriSource);
 22                 //文件路径
 23                 filePath = Path.Combine(CacheDirectory, uriSource.AbsolutePath.TrimStart('/').Replace('/', '_'));
 24                 this.OpenCatchSource();
 25             }
 26         }
 27 
 28  
 29 
 30         public string UriSource
 31         {
 32             get { return (string)GetValue(UriSourceProperty); }
 33             set { SetValue(UriSourceProperty, value); }
 34         }
 35 
 36         static StorageCachedImage()
 37         {
 38 
 39             //创建缓存目录
 40             using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
 41             {
 42                 if (!isolatedStorageFile.DirectoryExists(CacheDirectory))
 43                 {
 44                     isolatedStorageFile.CreateDirectory(CacheDirectory);
 45                 }
 46             }
 47         }
 48 
 49         /// <summary>
 50         /// 创建一个独立存储缓存的图片源
 51         /// </summary>
 52         /// <param name="uriSource"></param>
 53         public StorageCachedImage(Uri uriSource)
 54         {           
 55             uriSource = uriSource;
 56 
 57             //文件路径
 58             filePath = Path.Combine(CacheDirectory, uriSource.AbsolutePath.TrimStart('/').Replace('/', '_'));
 59             OpenCatchSource();
 60         }
 61 
 62         /// <summary>
 63         /// 放在xaml 需要这个构造方法
 64         /// </summary>
 65         public StorageCachedImage()
 66         {
 67             UriSourceProperty =
 68             DependencyProperty.Register(
 69             "UriSource",
 70             typeof(string),
 71             typeof(StorageCachedImage),
 72             new PropertyMetadata(new PropertyChangedCallback(UriSourcePropertyChangedCallback)));
 73 
 74         }
 75 
 76 
 77         /// <summary>
 78         /// 打开缓存源
 79         /// </summary>
 80         public void OpenCatchSource()
 81         {
 82             bool exist;
 83             using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
 84             {
 85                 exist = isolatedStorageFile.FileExists(filePath);
 86             }
 87             if (exist)
 88             {
 89                 SetCacheStreamSource();
 90             }
 91             else
 92             {
 93                 SetWebStreamSource();
 94             }
 95         }
 96 
 97         /// <summary>
 98         /// 设置缓存流到图片
 99         /// </summary>
100         private  void SetCacheStreamSource()
101         {
102             using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
103             using (var stream = isolatedStorageFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
104             {
105                  SetSource(stream);
106             }
107         }
108 
109         /// <summary>
110         /// 下载Uri中的图片
111         /// </summary>
112         private  void SetWebStreamSource()
113         {
114             var httpWebRequest = (HttpWebRequest)WebRequest.Create(uriSource);
115             httpWebRequest.AllowReadStreamBuffering = true;
116             httpWebRequest.BeginGetResponse(ResponseCallBack, httpWebRequest);
117         }
118 
119         /// <summary>
120         /// 下载回调
121         /// </summary>
122         /// <param name="asyncResult"></param>
123         private  void ResponseCallBack(IAsyncResult asyncResult)
124         {
125 
126             var httpWebRequest = asyncResult.AsyncState as HttpWebRequest;
127             if (httpWebRequest == null) return;
128             try
129             {
130                 var response = httpWebRequest.EndGetResponse(asyncResult);
131                 using (var stream = response.GetResponseStream())
132                 using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
133                 using (var fileStream = isolatedStorageFile.OpenFile(filePath, FileMode.OpenOrCreate, FileAccess.Write))
134                 {
135                     stream.CopyTo(fileStream);
136                 }
137                 Dispatcher.BeginInvoke(SetCacheStreamSource);
138             }
139             catch (Exception err)
140             {
141                 Debug.WriteLine(err.Message);
142             }
143         }
144     }

 

 

 

在XAML中引用

1  xmlns:StorageCached="clr-namespace:类所在的命名空间"

 

 

 

 

 参考 : .Net3.0里的DependencyProperty(1)

 

建议:适合场景广告或者背景等静态的位置

 备注: 这个方法还是有些要注意的地方,这个方法只适合于是用在静态的地方,不会连续要加载图片的地方,如果写在xaml的<list>中不会释放图片,会造成内存泄露,当然 BitmapImage这么用也是一样 , 如果是在代码中new 出的就不会有这些问题 

 我修改了下 在我的<List> 是这么用的 

 

<List>
....
  <Image Source="{Binding img}"  />

.....
</List>

 

vo.img = new StorageCachedImage(uri)

 

 

 

 

posted @ 2012-04-23 18:04  iiixxxiii  阅读(704)  评论(2编辑  收藏  举报