The given System.Uri cannot be converted into a Windows.Foundation.Uri

Tag: windows-8 , windows-runtime Author: mrwangjg84 Date: 2011-09-11

I'm trying to programmatically load a BitmapImage in a XAML Metro app. Here's my code:

var uri = new Uri("/Images/800x600/BackgroundTile.bmp", UriKind.RelativeOrAbsolute);
var imageSource = new BitmapImage(uri);

The second line crashes with a System.ArgumentException:

The given System.Uri cannot be converted into a Windows.Foundation.Uri. Please see http://go.microsoft.com/fwlink/?LinkID=215849 for details.

The link just goes to the MSDN home page, so it's no use.

I've also tried removing the leading /, in case WinRT has different expectations about relative URIs, but I still get the same exception.

Why am I getting this exception for what seems to be a perfectly valid URI?

Best Answer

In the Consumer Preview, the correct URL format has apparently changed to ms-appx:/Images/800x600/BackgroundTile.bmp

comments:

Can you link to some docs? I see from "How to reference content" that ms-appx works from JavaScript, but does it work for XAML-based UIs as well?
Yes, I can confirm that it works for XAML-based UIs, as well. I have not found any documentation on it - only trial and error led me to this result.

Other Answer1

Judging from the documentation for Windows.Foundation.Uri, it looks like WinRT doesn't support relative URIs. I tried a pack:// URI, but that gave me a UriFormatException, so apparently that's not the way to do it in WinRT either.

I found the answer on this thread: MS invented yet another URI format for WinRT resources. This works:

new Uri("ms-resource://MyAssembly/Images/800x600/BackgroundTile.bmp")

Note that you don't add your actual assembly name -- the MyAssembly part is literal text.

Other Answer2

You will need to use the page's BaseUri property or the image control's BaseUri property like this:

//using the page's BaseUri property
BitmapImage bitmapImage = new BitmapImage(this.BaseUri,"/Images/800x600/BackgroundTile.bmp");
image.Source = bitmapImage;

or

//using the image control's BaseUri property
image.Source = new BitmapImage(image.BaseUri,"/Images/800x600/BackgroundTile.bmp");

you can see the reason and solution here