How paths are resolved in Silverlight 2 can be somewhat confusing. This has come up a lot in the Silverlight.net forums and elsewhere, so I thought I'd take a stab at putting it all down here. For additional information on Silverlight 2 Beta 1 and how packaging and applications work, see my two part Xap/App posts here: Part 1, Part 2
Images with Leading Slash (like <Image Source="/foo.jpg" />)
This type of references, with a leading slash, is root relative to the application root (the Xap). These files should by Content and have CopyToOutputDirectory set so that they are added into the Xap. If you inspect the Xap, you'll find the image in there.
When not found, the resource loading mechanism falls back to the application's site of origin and looks for the image under the same dir as the Xap is located. Note that this is the application's site, not the hosting page's site. That is an important distinction if you are creating cross-domain applications (where Site X has the page and Site Y has the Xap). If not found, an exception is thrown.
Images without Leading Slash (like <Image Source="foo.jpg" /> )
This type of reference, without any leading slash or anything, expect to find the image compiled into the assembly as a Resource. The path is relative to the path of the Xaml file from which they are being referenced. When not found, the ImageFailed event is raised
If you inspect the Xap, you will not see the image, because it will be in the assembly.
Absolute URLs (like <Image Source="absolute http url" />)
This will look a the named absolute Url as you would expect.
Here's a quick example that shows it:
<UserControl x:Class="PeteBrown.SilverlightPathTest.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="Black">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!-- Image that is just content, with CopyToOutputDirectory -->
<Image Source="/Subfolder/image_content.jpg" Grid.Row="0" Grid.Column="0" />
<TextBlock Text="Content" Foreground="White" Grid.Row="0" Grid.Column="0" />
<!-- Image that is set as a resource, notice leading slash -->
<Image Source="Subfolder/image_resource.jpg" Grid.Row="0" Grid.Column="1" />
<TextBlock Text="Resource" Foreground="White" Grid.Row="0" Grid.Column="1" />
<!-- Absolute Url -->
<Image Source="http://www.irritatedvowel.com/pub/blog/SilverlightBalloonsforSilverlight2Beta1_B387/image.png"
Grid.Row="0" Grid.Column="2" />
<TextBlock Text="Absolute" Foreground="White" Grid.Row="0" Grid.Column="2" />
</Grid>
</UserControl>
Here are the settings in the project for the two files:
And here is the output:
If you look inside the generated Xap file, you'll see the following structure:
- PeteBrown.SilverlightPathTest.xap
- AppManifest.xaml
- PeteBrown.SilverlightPathTest.dll
- System.Windows.Controls.dll
- System.Windows.Controls.Extended.dll
- SubFolder
Recall that the image_resource.jpg file is compiled as a resource right into the PeteBrown.SilverlightPathTest.dll
Thanks to Ashish Shetty, PM from the Silverlight team, for helping to clear this up for me a while back.