Embed resources from a resource dictionary - wpf

I'm making an app with custom visual design. My plan is to reuse the custom design elements for other future apps as well, so I thought the use of a resource dictionary in a separate file would be a good idea.
Somewhere in the resource dictionary file I have some BitmapImage objects for use in various controls.
<BitmapImage x:Key="xIconClose" CacheOption="OnLoad" UriSource="C:\_x\source\Refs\EpicStyle\IMG\Frame\xCross.png"/>
<BitmapImage x:Key="xCheckboxChecked" CacheOption="OnLoad" UriSource="C:\_x\source\Refs\EpicStyle\IMG\xCheckbox_checked.png"/>
<BitmapImage x:Key="xCheckboxUnchecked" CacheOption="OnLoad" UriSource="C:\_x\source\Refs\EpicStyle\IMG\xCheckbox_unchecked.png"/>
<BitmapImage x:Key="xHeaderBTNMask" CacheOption="OnLoad" UriSource="C:\_x\source\Refs\EpicStyle\IMG\Frame\HeaderBTN.png"/>
The question is, how do I embed these linked image files in the built application?
Currently, when I build the application and the try to run it, it still uses the files from those locations. I would like to have a result where all the needed files are either embedded in the exe or somehow packed in some other resource file that would come with the built exe.
How would I do that for files defined in a resource dictionary?

Related

Loading external XAML file into a WPF project? The file is our "styles"

Has anyone had experience, or is it even possible to load an external XAML file into a WPF project from a hosted website.
We are wondering because we are defining the XAML file as our "styles". We would like a person not familiar with XAML to edit the file and then we don't have to redeploy the whole application, but next time the application loads it will just reference the changed XAML file.
Or is this not possible because the XAML files are compiled into the project?
Or would an option be to load an external XML file in code behind and populate our "style" properties that way? Is this possible?
We currently are using ResourceDictionary and calling an internal XAML file in the application, but we would like a more dynamic solution.
Using XamlReader.Load you can use the XAML parser. There is a performance hit from parsing XAML instead of BAML, and downloading a file from the network could negatively impact the (in my experience) often already slow startup times for WPF applications. The blog entry below provides a nice explanation of dynamically loading resource dictionaries.
http://blogs.interknowlogy.com/2011/09/02/xamlreader-looseresourcedictionaryfiles-parsercontext/

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.

Refer an image resource from Universal App shared project

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.../"/>

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

How to assign resource dictionary for custom controls in a dll

I have a WPF custom control MyControl.cs in my application project (.exe) with its style in a resource dictionary in MyControlResources.xaml. This xaml is specified in app.xaml as a part of the merged dictionaries. Everything works fine.
Now I want to move this custom control into an existing DLL project that the application references. Is there a way that I can create the resource dictionary "assignment" in the DLL and make it transparent to the callers i.e. the application project can use it like any built-in control that doesn't require you to know anything about resource dictionary?
I've read about creating a new custom control project can do the trick, but it's only one control for which I don't want to create a new project for. Anyone knows how to do it in an existing class library DLL?
This answer helped me find the trick.
Create a file called Themes\Generic.xaml to merge the resource dictionary.
Add the following attribute to Assembly.cs
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]

Resources