Referencing Resource Images in WPF Class Library without Citing Assembly Name - wpf

I have this WPF class library with several (local) images marked as Resource. They are located in a subfolder named Resources. To reference them, I use the following markup:
Icon="/AssemblyName;component/Resources/Logo64x64.ico"
And everything works fine in this assembly.
My problem is that I want to use that xaml file in several assemblies with different names. That is, AssemblyName is subject to change from build to build. Is there a way to reference the resource images without dependency on AssemblyName? Or can I use something that dynamically refers to assembly name in the markup? Something like:
Icon="/%AssemblyName%;component/Resources/Logo64x64.ico"
Or do I have to update the AssemblyName every time? Is it a good idea to define properties in the backing C# code and then use binding? I have been avoiding this because it looked like a lot of code to me for referencing each image.
As far as I know, you cannot use pack URI's in class libraries, right? Any help would be appreciated.
Thanks!

I don't know how I missed this, but it turns out I can totally avoid using AssemblyName, since the resources are local and they can be referenced relatively. In my case, the xaml file is in another subfolder, so the resource should be referenced as:
Icon="../Resources/Logo64x64.ico"

Related

Localizing text in XAML

From the outset of our project we've been storing strings in a resource file 'MyResources.resx', which was done to support the possibility of localizing the software in the future.
We've been using the following syntax for referencing the strings:
<TextBlock Text="{x:Static MyResources.Hello}" />
Is that correct, or should we be using the following:
<TextBlock Text="{Binding Source={x:Static MyResources.Hello}}" />
I've only recently come across the second syntax so I'm a bit concerned that what we've been using wouldn't actually change the text at runtime!
Also, is it okay to have the resx file in the main project, or should it reside in a project of its own? From the little I've seen about the localization process, it seems to involve generating a new DLL - is this a "full build" of the whole project, or does it (somehow) just extract the translated resx file(s) into the DLL?
For static localization, where you do not need to dynamically switch languages at runtime, your first example is the most straightforward solution. x:Static has relatively little overhead. It's nice and lightweight.
The second syntax won't make a difference in your case: the resource properties you are binding to do not raise change notifications, so the UI would not reflect any changes if you change MyResources.Culture at runtime. In either case, only newly created UI elements would reflect the new language.
If you do need to switch languages dynamically, neither of these approaches will suffice. There are some resources out there that can help you, but if you can get by with what you have, it'll make your life a lot easier. There's also a middle ground: you could create a custom MarkupExtension that takes in a text resource ID and provides localized text. Initially, it could simply delve into your resx resources, but you could potentially refactor it into a more dynamic solution later on (if and when you decide you need it).
From the little I've seen about the localization process, it seems to involve generating a new DLL - is this a "full build" of the whole project, or does it (somehow) just extract the translated resx file(s) into the DLL?
I believe what you're referring to is a satellite assembly. As I recall, satellite assemblies contain localized resources for a specific culture, but nothing more. You would bundle them with your main application or library, and the resource infrastructure will select which assembly to probe for resources based on the runtime CultureInfo.

Could not load 'Telerik.Windows.controls.FixedDocumentViewers'

I'm working with WPF and Telerik controls. I encapsulated RadPDFViewer inside ControlTemplate (I did that before for RadGauge and it works good), after I added all the required assemblies.
In the designer(user control) I can see the component as a gray rectangle but when I run the application it gives me error as u see in the attached file and it doesn't show me the component.
When I use RadPDFViewer not inside the ControlTemplate, in regular window it works fine.
Why only 'Telerik.Windows.controls.FixedDocumentViewers' can't be loaded (BTW all my assemblies) are the same version.
Thank you
The error you are getting is obviously around missing dependencies. The information you have given is not enough to respond with a definitive answer. So I will give you a best guess
You need to ensure that you copy to the output folder the assemblies Telerik.Windows.Controls.FixedDocumentViewers has a reference to. Not all references will be required as .net only loads assemblies when it requires them.
I will assume you are using the standard binaries and not the noxaml binaries.
So, using JetBrains dotPeek (a free .net decompiler), I got the following.
Telerik.Windows.Controls.FixedDocumentViewers has a dependency on the following
Telerik.Windows.Control,
Telerik.Windows.Documents.Core and
Telerik.Windows.Documents.Fixed
Telerik.Windows.Documents.Core has a Dependency on
Telerik.Windows.Zip.
and Telerik.Windows.Documents.Fixed has a dependency on
Telerik.Windows.Documents.Core
All of the assemblies has references to the usual suspects.
Since you appear to be playing with PDF files, you may need to load Telerik.Windows.Documents.FormatProviders.Pdf and if so, it has a dependency on
Telerik Windows.Documents.
and the other dependencies are mentioned previously.
To solve your problem, I would add the first 3 to your solution (Telerik.Windows.Controls is probably already added), and then add each of the other assemblies in turn until you find what you require.
I hope this helps.
In the VS Solution Explorer, right-click the Reference and make sure Copy Local is set to True.
I solved it. It's huge solution so I have to add this assembly to the startup project.
Thanks a lot

Generate dll file based on xaml and cs files

I have an application in WPF and I would do the following: In a folder I have a file .xaml that contains the screen, and a file .cs that contains the behavior of that screen. I need to generate a single .dll file from these two files (xaml an cs) and be able to access this .dll file within my application, so that this screen would make part of my application. I have no idea how to do this. Could anyone help me???
Thank's
Have you looked into Prism? It is useful for the scenario you describe, as long as you aren't trying to compile the screen at runtime. If that is what you're trying to do, I don't think you can associate a class with loose XAML.
If you have a ViewModel, and a View without code-behind, then you could potentially do this during the lifetime of the application. However, I think it will be far easier to compile these files, and have Prism load them as a module.

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

IlMerge Silverlight Class Library with Custom Controls

I am trying to merge all the assemblies of an class library in a single .dll file.
I can merge all the assemblies using the Ilmerge but is that when I use the merged dll in a Silverlight application I am having trouble when a template is apply to my control and binding problems if I use a control that inherits with UserControl.
is there any solution to solve this problem?
The problem is that when the initial dlls are built the Xaml in the project is added as a resource in the dll. The code generated to load this xaml will look something like this:-
System.Windows.Application.LoadComponent(this, new System.Uri("/SilverlightLibrary1;component/MyControl.xaml", System.UriKind.Relative));
Note how the name of the dll forms part of the Uri need to fetch the xaml. I doubt IlMerge is able to spot that and fix it up. Hence once merged the Uris cannot be found.
A resolution for this is probably uglier than multiple references or simply creating another project that links all the code files involved.

Resources