Refer an image resource from Universal App shared project - wpf

I just started work with winRT, shared projects etc. and faced with some problems.
I want to put all of my resources (strings, images etc.) in one project (portable class library or shared project).
When I put an image in PCL everything works fine in xaml by referencing with ms-appx:
<ImageBrush ImageSource="ms-appx:///Resources/Images/baby.jpg" Stretch="Uniform"/>
But when I put a string resource in PCL, I have following weird xaml behavior with ResourceDictionary:
http://postimg.org/image/ysbkvv6d7/
Ok. Then I decided to put every resources in Shared project. For this time it works perfectly with strings but fails with images: I couldn't get the right URI string in ImageSource of ImageBrush.
So the questions are:
How can I add ResourceDictionary in PCL
What is the correct URI format to reference image from shared project.
Thanks in advance!

To access an image your shared project file, just use the direct file path. The
<Image Source="Assets/ImageName.png"></Image>
Edited by #JerryNixon
<Image Source="ms-appx:///Assets/ImageName.png"></Image>
To access an image in your PCL, use the longer syntax
<Image Source="ms-appx:///ProjectName/...path.../"/>

Related

Why is my Image unable to locate the Resource?

I'm stumped. I am trying to display an image embedded in another assembly. I've tried several things, but nothing has worked so far. I'm convinced I'm missing something really simple.
Currently, the Xaml looks something like this:
<Image>
<Image.Source>
<BitmapImage UriSource="pack://application:,,,/Name.Of.Assembly;component/Resources/Icons/icon.png" />
</Image.Source>
</Image>
I originally had Xaml that looked like this:
<Image Source="pack://application:,,,/Name.Of.Assembly;component/Resources/Icons/icon.png" />
I switched it hoping it would make a difference. (It didn't.)
I have a reference to Name.Of.Assembly in the project I am trying to create an image. In the assembly, Name.Of.Assembly, there's a directory called Resources, which has a subfolder called Icons, which contains the image icon.png. The build action on icon.png is set to Embedded Resource.
When I try to run, I get a XamlParseException:
'Initialization of 'System.Windows.Media.Imaging.BitmapImage' threw an exception'
Whose inner exception is:
'Cannot locate resource 'resources/icons/icon.png'
It's like it's not looking in the assembly for the resource. Why does it fail to load the image? What am I missing?
I found a solution to my problem:
The first issue was probably having my build action set to Embedded Resource instead of Resource. Once I changed this I ran a Build on the project containing the resource, but I noticed nothing different.
Per Sean Nelson's suggestion, I did a Clean, followed by a Rebuild on the project.
The image is now displaying.

Set default xaml window background image in dll

I am currently developing a default WPF control Kit.
But I am stuck with using the correct kind of uri in xaml.
What I have is an image wich should be used as the background for the non-client area of my window.
To make the default controls available very easy I want to put everything in a dll.
Other apps can quickly reference that dll and get access to the style.
The problem is, that my image is not showing up when using the dll style in an app.
My image (/Resources/WindowBackground.jpg) is set to Resource and I am using the following xaml:
<Image Grid.ColumnSpan="99" Grid.RowSpan="99">
<Image.OpacityMask>
<ImageBrush ImageSource="pack://application:,,,/Resources/WindowBackground.jpg"/>
</Image.OpacityMask>
</Image>
I also tried:
<Image Grid.ColumnSpan="99" Grid.RowSpan="99" Source="/Resources/WindowBackground.jpg"/>
Both write the following into the output (Couple times):
..."System.IO.IOException" in PresentationFramework.dll...
I also tried lots of other uris wich sometimes lead to XamlParseExeptions and other not so nice stuff.
Thank you for any hints :D
You can find your answer in the Pack URIs in WPF page on MSDN. For your particular situation, you can use the following syntax to reference your resource image file:
pack://application:,,,/ReferencedAssembly;component/Resources/WindowBackground.‌​jpg
From the linked page:
The following example shows the pack URI for a XAML resource file that is located in a subfolder of the referenced assembly's project folder.
pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml
Note: The type of resource file here is irrelevant.

WPF Centralize xaml/image Resources in Multi-Tier/Project Application Solution

My situation is this.
I have multiple projects under a WPF solution which make up a multi-tier application I am developing. Since separate projects will sometimes need to access the same image or xaml resource I'd like to centralize "Public" resources to one project that can be referenced by any other projects requiring these "Public" resources. For example, I have a BMP image that I use in various controls and windows in separate projects that serves as a banner/logo. It seems like I should be able to add this image as a resource to the public resources project and reference it from my other projects instead of adding the image separately to every project that needs it. If this is possible, what would it look like and how should I go about doing it? If my idea just sucks I'm open to suggestions, but the project is going to be quite large so I don't want to be adding resources all over the place.
Thanks!
P.S.
I have searched this topic quite a bit but there are so many garbage answers out there from people that don't know what they are doing. Given that I'm relatively new to WPF I'd rather get a direct answer to my problem.
Well after some tinkering and research I found a solution to my own question. It seems like bits and pieces of my answer were scattered all over the web so I'll try to explain the whole thing at once, in one place. To re-cap I basically wanted to centralize any resources used across projects within my solution. These are the steps I eventually followed to accomplish this.
1.
Create a User Control project in your solution (any project that can host Resource Dictionaries will do). I'll refer to this project as "the resource project".
2.
Add any resource files (images etc...) that you want to share between projects to the resource project. I try to organize files in sub-directories that make sense. You will want to set the build action to "Resource" so that it gets compiled into the output binary.
3.
Now add a resource dictionary to the resource project. In my case I wanted to reference several images so I made one called "ImageDictionary.xaml".
4.
Add references to the image files in the resource dictionary. I am referencing images here but its just a resource dictionary, you can put whatever in there. The string in the middle is just the relative path to the image file you are referring to.
<ImageSource x:Key="SomeImageKey">
Images/SomeImage.bmp
</ImageSource>
5.
Now go to a project that requires the resource dictionary you just made in step 4. It can be another user control or a window, whatever. Right-click on project references and add a reference to the resource project.
6.
Okay now the current project needs to reference the dictionary you made in step 4 that is defined in the resource project. I made a user control first so this is what my code would look like below... Note that I used merged dictionaries. I plan on using more later so I chose this way instead of a single dictionary.
"ResourceProject" below is the name of the project/assembly that you added the resource to.
"component" is a keyword that needs to be there, followed by the path to the dictionary xaml code file.
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ResourceProjectAssembly;component/Resources/ImageDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
As you can see, referencing an external resource dictionary requires something called a "Pack URI". I found a short hand way of doing it. The long way is quite a bit uglier and as far as I know, there is no advantage to it. But here is what the long way looks like.
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/ResourceProjectAssembly;component/Resources/ImageDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
7.
Now that your current project has a reference to the resource dictionary in the resource project, you can use anything from that dictionary. I went ahead and put an image in my user control. Below is the code. Its just like referencing a dictionary locally.
<Image Source="{StaticResource SomeImageKey}" />
8.
Important Note!
This caused me a headache for a while before I found it. Make sure that the startup project in your solution has a reference to the resource project EVEN IF THE STARTUP PROJECT DOES NOT USE THE RESOURCE PROJECT. (I.e. right-click references, add reference etc...)
The resources will not get compiled into the output unless you do this. This part was tricky because the designer was even showing my images and I had no xaml errors but at runtime it would throw set property and cannot find file exceptions. This went away when I referenced my resource project from my startup project.
Hopefully this helps somebody.
Below are some links to a few places (including stackoverflow) that gave me what I needed to put all the pieces together.
http://blogs.msdn.com/b/wpfsldesigner/archive/2010/06/03/creating-and-consuming-resource-dictionaries-in-wpf-and-silverlight.aspx
Load WPF styles or other Static Resources from an external file or assembly
ResourceDictionary in a separate assembly

Use a embedded Image in a Button Template in Silverlight 4

I would like to build a Template for my (edit)Buttons in Silverlight 4.
Therefore I want to include the Images as a embedded resource.
So my question is:
How can I use the embedded ressource images in the template for my button?
The ControlTemplate (TargetType="Button") is located in one external Ressources.xml.
regards
Christoph
In Silverlight you should be using "Resource", never "Embedded Resource" as the build action for resources.
The MSDN Reference on Resource Files gives a very good overview of resources in Silverlight and the URIs you should use to reference them. It also goes over the default fallback mechanisms used when the referenced file is not immediately found.
In general, you would reference an image source by a path relative to the referencing XAML like this:
<Button>
<Image Source="path/to/myimage.png"/>
</Button>
If the embedded image resource is located in a different assembly from the referencing XAML, you can use the short assembly name and component keyword like this:
<Button>
<Image Source="/MyShortAssemblyName;component/path/to/myimage.png"/>
</Button>

Why does the Image element give me a design-time error with "add as link"ed images?

I need to display an image, which I've done without problems before, but today I decided to be tricky and use "add as link" instead. Well, now I get:
The file Images/hello.png is not part of the project or its 'Build Action' property is not set to 'Resource'.
Wait... its Build Action is set to Resource. I've seen a Silverlight solution that involves the usage of Merged Dictionaries to share files between Silverlight and WPF projects, but it's not clear to me that this would even apply to my WPF + Image issue.
Has anyone solved this problem before? I could make copies of all of the images, but that seems a little silly if I have a shared repository with clip art and the like.
Dave,
I've just tried to add image as a link to plain WPF application. Build action is "Resource" (don't confuse with "Embedded Resource"). I've added it to the root, and refer to it as <Image Source="/file_name.jpg"/> - all works fine.
The message you have is it compile or runtime? If it's a runtime, how do you refer to the image? Do you see it in Reflector, when you open your assembly (it should be under Resources folder)?
I have images in one assembly which I want to share into another. I've used Add as Link in my second assembly. In the project where the actual image files are located they are in a Resources\Images folder. In the project which links to those files the links are also in a Resources\Images folder. At runtime a XamlParseException claiming "cannot locate resource" is thrown.
My xaml which is referencing the image is in a UserControls folder.
In the project which actually contains the images the path ..\Resources\Images\Blah.png works fine as expected.
Opening the DLLs in Reflector makes it obvious that in the assembly with the linked images holds the images at the root level - the compiler is not respecting the folder location. So in the project with the linked files I have to use ..\Blah.png to find the resource.
Surely a bug in the compiler?

Resources