Image Caching
While the viewmodel saves the result of the
WCF service call, which allows the app to restore its state after being
tombstoned, downloaded images are not saved in the state dictionary,
but rather, the app relies on some custom image caching.
A custom IValueConverter
, called ImageCacheConverter
, is used to download the image from the specified image URI, as shown in the following excerpt:
<Image Source="{Binding Product.LargeImageUri,
Converter={StaticResource ImageCacheConverter}}" />
By using the ImageCacheConverter
,
images can be downloaded once and stored in isolated storage for an
arbitrary period. When that period has elapsed, the image is downloaded
again. This allows the application to work offline (see Listing 7).
LISTING 7. ImageCacheConverter
Class
public class ImageCacheConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
if (EnvironmentValues.DesignTime)
{
return value;
}
string url = value as string;
if (url != null)
{
try
{
return ImageCache.GetImage(new BitmapImage(new Uri(url)));
}
catch (IsolatedStorageException e)
{
Console.WriteLine(e);
return value;
}
}
BitmapImage bitmapImage = value as BitmapImage;
if (bitmapImage != null)
{
return ImageCache.GetImage(bitmapImage);
}
return value;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
The ImageCacheConverter
can be used in conjunction with a URL or a BitMapImage
. In the sample code, it is used with a URL, supplied by the product’s SmallImageUri
and LargeImageUri
properties. The ImageCache
class maintains a dictionary of URI keyed cached images. It stores the
dictionary in isolated storage, and when an image is requested, it
attempts to locate it in the dictionary. If found it checks to ensure
that the image has not expired, and then returns the image.
The ImageCache
class, in the downloadable sample code, maintains a list of ImageCacheItem
objects, which represent cached images. The ImageCache.GetImage
method is used to retrieve an image from the cache. If the image is not
located in the cache, it is scheduled to be downloaded by the static ImageDownloader
class.
The ImageDownloader
coordinates an asynchronous download of the image file. It uses an HttpWebRequest
to retrieve the image from a remote server, and then stores the downloaded file in isolated storage. Once downloaded, the Source
property of the original image is assigned, which means that, if it is present in the UI, the image will appear (see the ImageDownloader
class, located in the Data/ImageCache directory of the WPUnleashed project, in the downloadable sample code for details).