Making XAML Designer load ResourceDictionary from file in WPF hosted app - c#

I have a WinForms project which uses hosted WPF controls. I have a resource dictionary saved in my Resources which I load into my Application object at runtime using the following code placed before System.Windows.Forms.Application.Run():
new System.Windows.Application();
System.Windows.Application.Current.Resources.MergedDictionaries.Add(
System.Windows.Application.LoadComponent(
new Uri("/MyApp;component/Resources/Styles.xaml",
UriKind.Relative)) as System.Windows.ResourceDictionary);
Which works fine in the end application, but the problem is, as it is loaded at the runtime, that file is not loaded by the Designer. Is there a way to make the XAML Designer load this file in my control (at least for UI building purposes)?

Okay, I got this.
You can load ResourceDictionary from within the xaml with the following code:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MyApp;component/Resources/Styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
Just delete this after designing the control to keep things clean.

Related

Styles from resource dictionary not found in user control

I have a resource dictionary with a bunch of styles that I am linking too in my user controls like so:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Theme/ThemedResources.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
This all works fine during runtime.
However I get a recurring problem in that one of the styles in the resource dictionary 'cannot be found' in whichever user control is the most recent, until the solution is rebuilt. This error will then appear again after I stop the debugging process, and again will disappear with a rebuild.
I don't think this is linked to a specific style, as when I add new styles the style that can't be found seems to change.
Any ideas how I can stop this from happening?
You have used a Relative URI, so it will looks for your resource file in a somewhere that you used your UserControl. It can't find you resource file because your resource file is not in the AbsolutePath.
AbsolutePath = CurrentPath (r.g Where you used your UserControl) + RelativePath
so Use an AbsolutePath:
<ResourceDictionary Source="pack://application:,,,/{YourAssemblyName};component/Theme/ThemedResources.xaml" />

ResourceDictionary in wpf as dll application

Let's start from the beggining. I have an app in wpf which uses my custom window style. I'm defining this custom style in app.xaml like below:
<Application x:Class="GeoLocations.Test.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ThemedWindowStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Nowadays there came a requirement that i need to build this application as dll and later on call it from Windows.Forms application. Obviously the app.xaml code is not being fired since this is not start up application anymore. Is there any way to load it ?
I tried to manually register this Dictionary in code behind but with no success. I also tried to change Build Action from "Page" to "Content" and "Do not copy" to "Copy if newer" but it is giving me different exception:
'Failed to create a 'Type' from the text 'local:ThemedWindow" with inner exception "{"Type reference cannot find type named '{clr-namespace:GeoLocations.Test}ThemedWindow'."}
(this exception is beeing fired inside ResourceDictionary so it's loaded but why it can't find the type ?).
ThemedWindow is a type which inherits from Window and later on all my windows inherits from ThemedWindow instead of Window
I have no idea how to solve this issue. Anyone got some knowledge to help ?
Ok, so i resolved this be adding my ResourceDictionary in code behind in my ThemedWindow Constructor. Like below:
var rd = new ResourceDictionary();
rd.Source = new Uri("pack://application:,,,/GeoLocations Screens;component/ThemedWindowStyle.xaml");
Resources.MergedDictionaries.Add(rd);

WPF's application wide styles in Windows Forms context

We migrate from WinForms to WPF... slowly =)
No we use WPF User Controls with ElementHost.
Is it possible to define application wide resources in this context? In pure WPF Application.Resources stands for it. But there's no WPF App when integrating with WinForms.
You can use a WPF application object even if your project is a WinForms one with a few separate WPF forms or controls. The object won't be precreated for you, but if you manually create it, simply by new App() (or even without a derived class, new System.Windows.Application()), everything in your project will see it.
You can create a common ResourceDictionary and add it to the Resources of your UserControls. That way you just have to change your Styles in one location.
Dictionary1.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</ResourceDictionary>
and add it to your UserControl using MergedDictionarys
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
or just add it to the Control's Resources like this
<UserControl.Resources>
<ResourceDictionary Source="Dictionary1.xaml"/>
</UserControl.Resources>

WPF Prism - Where to put Resources?

I have a prism application and various modules. I am wondering where is the best place to locate resources such as styles, brush, controltemplates, datatemplates?
Should I make one single resource dictionary and put everything there? Should each module have their own resources? Or each view? I would like to follow the Prism goal of keeping everything modular, but also I dont see the point in re-declaring the same resources in every module...
I develop application with Prism, and I use technique very close to described in Prism's manual. There is YourApplication.Infrastructure project, where you usually place all your shared interfaces etc. So:
I just add project YourApplication.Resources
Create there folder Themes
Create separate xaml file in Themes folder for each group of resources (like Generic.WPF.xaml for standard WPF controls' styles, Generic.Brushes.xaml for brushes etc.)
Create file Themes\Generic.xaml (exactly with this name, it will add huge benefits in the future) with content like
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Generic.Brushes.xaml"/>
<ResourceDictionary Source="Generic.WPF.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Now you can add those resources in any module (you have separate project for it, right?) by adding reference to YourApplication.Resources to that project and adding to your view's xaml:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/YourApplication.Resources;component/Themes/Generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
<!-- Put your not shared resource here -->
</ResourceDictionary>
</UserControl.Resources>
I don't know, maybe this way has some problems, but it works, and works well for me. If anybody can comment somehow this way (pros/cons) - I will be very happy to hear it!
Application-wide resources I usually put in a ResourceDictionary, which is added to either App.xaml or StartupWindow.xaml
Resources for a specific View are usually located with the View. For example, a UserControl that is being used for a CalendarView will contain any custom resources for the Calendar, such as calendar-specific brushes, styles, templates, etc.
I usually don't see a reason to make module-wide resources, but if I ever do I'd have a ResourceDictionary for the Module which can be loaded into the app's merged dictionaries at runtime, or included in individual Views in the Module.
I would like to share some new knowledges. I am using #chopikadze approach. And it is really cool approach. Thanks to you!
However, if you do not want write every time for each control these piece of code:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/YourApplication.Resources;component/Themes/Generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
<!-- Put your not shared resource here -->
</ResourceDictionary>
</UserControl.Resources>
Then you can just declare <ResourceDictionary/> in App.xaml of your Bootstrapper like that:
<Application.Resources>
<ResourceDictionary Source="pack://application:,,,/YourApplication.Resources;component/Themes/Generic.xaml"/>
</Application.Resources>

Xaml: C# How to keep style consistent

I'm working on a semi-large windows application using wpf and C# in VS 2010. While working on the xaml, I added a tag so that all buttons and datagrids are styled in the same way. I've copied and pasted this block into several of my .xaml files and that works fine. Of course the problem I'm running into now is that I've added to and changed the style several times.
What is the best way to keep style consistent between my different Windows? Is it subclassing, using Resources.resx, or another way enirely?
If you define the style in the Application level ResourceDictionary (App.xaml), then it will automatically be inherited by your other XAML Windows/Controls.
yeah, if you were to create a new file called Resources.xaml and then add this to your Application.xaml file:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
then you should be able to reference the styles in the Resources.xaml from all the windows in your application.

Categories