Referencing a picture in another DLL in Silverlight and Windows Phone 7

This one has burned me a few times, so here is how it works for future reference:

Usually, when I add an Image control into a Silverlight application, and the picture it shows is local (as opposed to loaded from the web), I set the picture’s Build Action to Content, and the Copy to Output Directory to Copy if Newer. What the compiler does then is to copy the picture to the bin\Debug folder, and then to pack it into the XAP file. In XAML, the syntax to refer to this local picture is:

<Image Source="/Images/mypicture.jpg"
       Width="100"
       Height="100" />

And in C#:

return new BitmapImage(new Uri(
    "/Images/mypicture.jpg", 
    UriKind.Relative));

One of the features of Silverlight is to allow referencing content (pictures, resource dictionaries, sound files, movies etc…) located in a DLL directly. This is very handy because just by using the right syntax in the URI, you can do this in XAML directly, for example with:

<Image Source="/MyApplication;component/Images/mypicture.jpg"
       Width="100"
       Height="100" />

In C#, this becomes:

return new BitmapImage(new Uri(
    "/MyApplication;component/Images/mypicture.jpg", 
    UriKind.Relative));

Side note: This kind of URI is called a pack URI and they have been around since the early days of WPF. There is a good tutorial about pack URIs on MSDN. Even though it refers to WPF, it also applies to Silverlight

Side note 2: With the Build Action set to Content, you can rename the XAP file to ZIP, extract all the files, change the picture (but keep the same name), rezip the whole thing and rename again to XAP. This is not possible if the picture is embedded in an assembly!

So what’s the catch?

Well the catch is that this does not work if you set the Build Action to Content. It’s actually pretty simple to explain: The pack URI above tells the Silverlight runtime to look within an assembly named MyOtherAssembly for a file named MyPicture.jpg in the Images folder. If the file is included as Content, however, it is not in the assembly. Silverlight does not find it, and silently returns nothing. The image is not displayed.

And the fix?

The fix, for class libraries, is to set the Build Action to Resource. With this, the picture will gets packed into the DLL itself. Of course, this will increase the size of the DLL, and any change to the picture will require recompiling the class library, which is not ideal. But in the cases where you want to distribute pictures (icons etc) together with a plug-in assembly, well, this is a good way to have everything in the same place Smile

Happy coding,

Laurent

 

Print | posted on Sunday, February 13, 2011 11:13 PM

Feedback

# re: Referencing a picture in another DLL in Silverlight and Windows Phone 7

left by Olivier Dahan at 2/14/2011 4:14 AM Gravatar
Pour tous ceux intéressés par le sujet mais en français, j'ai écrit un billet sur ce sujet début janvier "Lire un fichier en ressource sous Silverlight" (http://www.e-naxos.com/Blog/post.aspx?id=84e98418-c674-4714-bbbc-a18df12776ec).

# re: Referencing a picture in another DLL in Silverlight and Windows Phone 7

left by Daniel at 12/23/2011 12:10 AM Gravatar
Thanks you very. I really needed that for my new Silverlight-Game! Stay tuned...

# re: Referencing a picture in another DLL in Silverlight and Windows Phone 7

left by Daniel at 12/23/2011 12:11 AM Gravatar
Thank you very much. I really needed that for my new Silverlight game! Stay tuned...
Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: