Not able to reference Image source with relative path in xaml

Answers to such questions are often confusing because the principles/prerequisites for the solution to work are not explained correctly. This is the case with the currently selected answer too. So it's a good thing to be aware of:

  • The different ways to manage and reference a file/resource added to the project.
  • How to specify in the markup the URL for a file managed as Content.
  • The non-required use of the pack URI instead of the simple URL

Things to consider:

1. How to declare the type of file/resource you are adding to your project.

This is done by adding appropriate folder and files to the project using the Solution Explorer in VS, e.g. in a subfolder Images:

enter image description here


and specifying properties for each added file (on the right side below):

enter image description here


The Build Action is set to Content and the Copy To Output Directory is set to Copy if newer. This is how files should be added when you don't want them to be embedded into the assembly.

  • For reference, the Content option is one of the possible options to access a file in WPF. Other options include Resource (either embedded in the current assembly, or in another assembly of the same application) and Site of Origin to access a file which has no relationship with the current application:

    enter image description here
    Source

Content type files are linked to the executable (assembly) only by the relative path they are stored. The relative URL is stored in assembly metadata. These files are expected to be found at execution time, but they can be changed/updated without recompiling the assembly.

The Copy if Newer value means the compiler will take care of copying the original file to the right place during the assembly building process, so that the relative path is preserved, e.g. if a file is located in the subfolder Images of the project, e.g. MyProject/Images then a copy will be created in MyProject/bin/Debug/Images when the application is compiled in debug mode. The assembly being built in MyProject/bin/Debug, the relative path is the same.

2. How to specify a Content file URL in the markup.

This is the easy part, and usually the only one explained. But it works only if the previous step has been done correctly.

To use a content file, just use the markup shortcut of the relative path (relative to the assembly): <Image Source="Images/Lighthouse.jpg"/> (there is no leading /).

Other cases, where the file is not declared as Content type (e.g. an image which must be embedded into the assembly as a Resource, or a file which must be loaded from the network) involve syntax variations with the simple URL replaced by a pack URI.

3. Non-required / excessive use of the pack URI.

As the URI scheme can be used to reference anything, the pack URI solution is often proposed to also reference files declared as Content. For our example, the equivalent pack URI would be: pack://application:,,,/Images/Lighthouse.jpg (note the leading /).

However the URL shortcut is more appropriate, and less error-prone for a standalone file which location relative to the assembly is known at design time.

For a more detailed view see:

WPF Application Resource, Content, and Data Files


I got this working by:

  1. Name of my WPF User Control project: WpfControls

  2. Name of the folder containing the image: Images

  3. Name of the imgae file: Asdf.png

  4. Include the folder and image file into the WpfControls project

  5. The image file's Build Action set to Resource

  6. The Source property in the Image tag set to:

    <Image Source=/WpfControls;Component/Images/Asdf.png" />


If Images folder is added in same project of its usage, this should work for you:

<Image Source="/Images/Folder-icon.png"/>

Or use Pack Uri specifically:

<Image Source="pack://application:,,,/Images/Folder-icon.png"/>

In case image resides in different project than current project where your XAML resides, you have to use more verbose definition of Pack URI where you have to specify the assembly name where image is added.

<Image Source="pack://application:,,,/Assembly;component/Images/Folder-icon.png"/>

Replace Assembly with actual assembly name where image is added into.


Also make sure Build Action is set to Resource for file Folder-icon.png.


UPDATE:

More verbose definition of Pack URI works in sample as well. Try this out:

<Image Source="pack://application:,,,/ClassLibrary1;component/Folder-icon.png"/>

Tags:

C#

Wpf