WPF & Images

WPF & Images

tamas.deri
Advocate Advocate
1,595 Views
7 Replies
Message 1 of 8

WPF & Images

tamas.deri
Advocate
Advocate

I've noticed a slightly strange behaviour of images on wpf forms used in Revit.

The scenario is the following:

I have a simple .NET solution, with a basic C# class library project and a shared project. If I add any png image in the shared project, into any folder, set its Build Action to Resource, and Copy to Output Directory to Do Not Copy, I can use this image on my wpf form with a simple

 

<Image Source="image_name.png"/>

 

xaml element, and it is visible both in visual studio and in Revit.

If I add the same image to the class library project with the same settings as before, I have to reference it in the xaml with the full relative path like

 

<Image Source="/path_to/image_name.png"/>

 

to make it show up in visual studio, but it will still not be visible in Revit.

So in the end if I have in the xaml:

 

<Image Source="image_in_shared_project.png"/>
<Image Source="\Resource\image_in_class_library_project.png"/>

both of them will be visible in visual studio, but only the first is visible in Revit.

 

Could someone please explain to me the reason and the mechanics of this behaviour? I would like to have the most optimal way to include image files in the built assembly, without copying png files over to the output directory..

Thanks!

 

0 Likes
1,596 Views
7 Replies
Replies (7)
Message 2 of 8

Kennan.Chen
Advocate
Advocate

Where did you use the image? the shared project or the library project?

0 Likes
Message 3 of 8

tamas.deri
Advocate
Advocate

I'm using the images in the library project, the shared project is only for common resources, entitlement management, etc.

0 Likes
Message 4 of 8

068335643
Advocate
Advocate

I think after build you won't see the images. use something like this

 

<Image Source="/myproject;component/Resources/Logo.png" />


and  in properties of Image set  building action - Resource 


 

0 Likes
Message 5 of 8

Kennan.Chen
Advocate
Advocate

Accessing embedded images in WPF via "pack Uri" is a widely accepted method of accessing images in XAML. When specifying a path to the Image.Source property in XAML, WPF automatically binds a URI with that path to the Image.SourceProperty internally. It is important to note that the XAML code is also a kind of embedded Resource just like an image, which means the binding process occurs at runtime, which also means that the path looks less straightforward as what you would expect at compile time.

 

This article may help you.

 

EDIT:

Imagine a piece of HTML code like this:

<html>
  <body>
    <img src="/my-image.png">
    <img src="http://another.site/another-image.png">
  </body>
</html>

The html code is fetched by the browser as a resource from the server. The server here is neither the physical machine nor the operating system that runs remotely. It's an application that runs remotely. The application picks a folder in the OS as its root and returns resources relative to that folder. It is a thought of virtualization to keep things stable without caring about where you put those files in the file system of the physical server.

I personally believe that XAML shares the same thought to define those embedded resources.

 

For "pack Uri", read this article for more detail

0 Likes
Message 6 of 8

tamas.deri
Advocate
Advocate
Thanks, I will have a look into this, and get back with the results!
0 Likes
Message 7 of 8

tamas.deri
Advocate
Advocate

I have the same issue using pack uri... The image is visible in visual studio, but not in revit.

<StackPanel Grid.Row="0">
  <Image Source="pack://application:,,,/Resources/logo1.png"/> <!--visible in studio, not in revit-->
  <Image Source="/Resources/logo1.png"/> <!--visible in studio, not in revit-->
  <Image Source="pack://application:,,,/SBShared;component/Resources/ViewIcons/logo2.png"/> <!--not working at all, file not found-->
  <Image Source="logo2.png"/> <!--visible both in studio, and revit-->
</StackPanel>

 

Also, any image set to resource in the shared projects .projitems file it will show in studio as not included. If I include it in the project, once I set the Build Action to Resource it gets automatically excluded...

0 Likes
Message 8 of 8

RPTHOMAS108
Mentor
Mentor

Pack URIs are resolved with respect to the entry assembly this is likely null for a Revit add-in although I've not checked. This issue is similar to the assembly reference probing issue where it starts in the wrong place (Revit.exe folder).

 

If you set the property noted by the below linked article then you should be able to use the pack URI system as intended. However to be honest I've previously got it working without via trial and error.  

 

However the article describes the scenario of a WPF assembly hosted by a native process which I believe is the usage case example for Revit add-ins.

 

Application.ResourceAssembly 

 

You can only set it once it says, I assume once per add-in although I've not tested. Would be pointless if only one add-in could set it. Really depends how they have incorporated the API system into the main Revit process.

 

Otherwise we have to have an annual vote as to who gets to set it! That person has to store everyone else's resources in a mega assembly.

0 Likes