In this post we will look at how application data files can be referenced using relative Uris from within XAML or code in your Silverlight 2 application.
Silverlight provides you with a luxury of choices for how you declare your application data files. These are the non-code artifacts of your app, such as images, videos, fonts etc. The build action for any file - i.e. how you declare it in your project file or within Visual Studio or Blend - is consequential to how it can be referenced in XAML or code via a Uri. While care was taken to ensure defaults that gel with the programmers intuitiveness while referencing them in Uris, there are always subtle issues that the intrepid Silverlight designer or developer must be aware of. If you come to Silverlight with previous WPF experience, the contents of this post should be old news to you. If not, fear not; Silverlight is designed to be easy to learn and easy to master.
Let's take Image files as an example as we walk through the various cases. Once you understand how this works, you can extrapolate behavior for MediaElement (audio/video) or MultiScaleImage (SeaDragon in Silverlight) or perhaps even fonts. While examples below show XAML syntax, the same applies to code.
Files marked as Resource:
- Get embedded in the app assembly within the XAP
- Are accessible using a relative Uri, relative to the XAML file from where they are being referenced
For e.g. <Image Source=”Foo.jpg” />
- When not found, there is no fallback. The ImageFailed event is raised.
Tip: Using assembly qualified Uris is most reliable both from within and outside that assembly. E.g. <Image Source=”/{assemblyShortName};component/Foo.jpg”/>
Tip: You can programmatically extract any application resource using Application.GetResourceStream(uri).Stream
.
Files marked as Content:
- Get added to the XAP at the conceptual application root
- Are accessible using a relative Uri, relative to the application root. This requires the use of a leading slash
For e.g. <Image Source=”/Foo.jpg” />
- When not found, the resource loading mechanism falls back to the application’s site of origin and looks for the image under the same (web root) dir as the XAP is located
- When not found, the ImageFailed event is raised.
Tip: this is a no-brainer when you have a resource that is commonly used from within 2 assemblies in the XAP
Files marked as None (with CopyToOutputDirectory set appropriately):
- Don’t get copied into the XAP, but the CopyToOutputDirectory metadata will ensure it gets copied alongside the XAP
- Are accessible using a relative Uri, relative to the application root. This requires the use of a leading slash
For e.g. <Image Source=”/Foo.jpg” />
- This is the fallback path of the above
Tip: in most cases you want to keep your video files out of the XAP. They are not encumbered by x-domain download restrictions. You do not get compression benefits from keeping them in the XAP. Rather you can use streaming or progressive download if they are outside.
Files marked as None, as well as image and audio/video files not marked at all in the project (i.e. external to the project), can always be referenced using absolute Uris.
Files marked as EmbeddedResource:
- Get embedded into the assembly in a manner that Silverlight cannot use for URI references either from XAML or code
- Should be changed to Resource, and used as detailed above.
Hopefully this demystifies Uri usage in Silverlight for you. If we can make improvements in the runtime or in tools to make this easier for you, please post a comment here. Feedback is always appreciated.
Related links:
Labels: Content, EmbeddedResource, Resource, Silverlight, URI
Email this | Bookmark this