Martin Suchan – BloQ Random #WPdev stuff

31May/133

Image path databinding in WP8 and Windows 8 apps

I don't like lengthy articles, so let's make it short and easy.
When you are developing Windows Phone 8 or Windows 8 "modern" apps, you surely want to display images in it.
For displaying images the well known Image element is used:

<Image Source="imagepath"/>

The imagepath can have multiple values, it can be:

  • Uri address to image located on the Internet
  • path to image located in app resources/app installation package
  • path to image located in app isolated storage

The interesting point is that I've discovered only today that it is actually possible in WP8 apps to display images located in isolated storage directly just by defining the Source, without any loading to Stream and BitmapSource. That's right, even if you search on StackOverflow or on MSDN  how to display images located in isolated storage using path in WP8, they tell you it's not possible.

Yes, it is possible, and the whole magic it so use absolute image path using the StorageFile.Path property. Now you know the secret, but let's check it in detail.

So how it works? I've created simple Windows 8 and Windows Phone 8 application, it contains list of ImageModel classes, each containing image Uri and Comment. I'm also downloading two images from web to isolated storage to test the image loading using just path. The complete list of image paths I use:

  • Remote image located on Internet
  • Local image with 'ms-appdata' uri scheme
  • Local image with full file path (the secret)
  • Resource image with 'ms-appx' uri scheme
  • Resource image with direct relative path
  • Resource image with full file path

The viewmodel with these 6 paths will be now used as the ItemsSource for ItemsControl with custom ItemTemplate, in which we'll show Image bound to the actual path, TextBlock displaying the Uri and comment.

If you haven't created any Windows 8 app before, you might read this MSDN describing the Uri schemes for referencing files in Isolated Storage and in app resources.

So let's start the WP8 and Windows 8 app with the same viewmodel and check the results:

Left is screenshot from WP8 emulator, right is from Windows 8 app

wp8 win8

 

We can see that even when using same images, same Uri sources, same XAML and even though both platforms are based on Windows Runtime and they have lot of in common, the result is different, but why?

Let's check each path in detail:

  1. Remote image path - this works on both platforms as expected, nothing here, move along
  2. Isolated storage path using the ms-appdata:/// uri scheme, this works as expected on Windows 8 but not on WP8. I'm not sure why it's not implemented, it might working be in the upcoming Windows Phone 8.1 OS.
  3. Full Path of the StorageFile representing the image file. To my great surprise this works on WP8 and you can use it for simple image path databing for files located in Isolated Storage, but it's not working on Windows 8. Again, no idea why. Maybe it wasn't implemented by purpose, or by mistake. Or maybe the full path Image source works on WP8 as a replacement for the missing ms-appdata Uri scheme . This is surely undocumented feature, but be sure to know it and use it, it works!
  4. When referencing resource files in app package we can use the ms-appx:/// uri scheme, this works again only on Windows 8, not on WP8, but this might change in the future.
  5. When referencing resource images we don't have to use Uri scheme or full path, we can use just relative local path and it works just fine on both platform. I'm sure you already know this.
  6. In the last example I've used again the full StorageFile.Path and again this works only on WP8 but not on Windows 8.

So what is the conclusion here? On both platforms WP8 and Windows 8 you can use simple path for displaying images located on Internet, in IsolatedStorage or in Resources, but you need to know which type of path works on which platform. For referencing Internet images just use the actual Uri, for referencing resource images I would recommend using the relative local paths, and for displaying files stored/cached in isolated storage use ms-appdata:/// uri scheme on Windows 8 and StorageFile.Path on WP8.

Remarks: the solution with StorageFile.Path cannot be used on WP7, because StorageFile class isn't in WP7 API. As far as I know it's not possible to show images located in isolated storage in WP7 apps using just path, you have to use the stream loading into BitmapSource. Another remark, some of you may know another Uri scheme used in WP7 and WP8 for referencing files used for live tiles: "isostore:/Shared/ShellContent/img.jpg" or as lockscreen images: "ms-appdata:///Local/Shared/ShellContent/img.jpg". One might think the same Uri can be used for Image source, but the true is it doesn't work. For some reason it works only when used for tiles or lockscreen.

Here you can download simple sample I've used for creating these images, enjoy! Also let me know if you know any similar trick related to Uri schemes and Isolated Storage.

And if you're not interested in downloading full project, here's the magic WP8 Isolated Storage image path gathering:

/// <summary>
/// Get path for image located in Isolated Storage.
/// </summary>
private string GetIsolatedStorageFullImagePath(StorageFile file)
{
#if NETFX_CORE
    return Path.Combine("ms-appdata:///Local/", file.Name);
#elif WINDOWS_PHONE
    return file.Path;
#endif
}
Filed under: Windows 8, WP8 Leave a comment