I have a UI project containing (so far) 18 XAML resources, which are merged into App.xaml like so:-
<Application ...>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/foo.Client.Common;component/UIStyles/Colours.xaml" />
<ResourceDictionary Source="pack://application:,,,/foo.Client.Common;component/UIStyles/Buttons.xaml" />
<ResourceDictionary Source="pack://application:,,,/foo.Client.Common;component/UIStyles/Menus.xaml" />
// etc..
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
When I edit any of the XAML views in this project I get intellisense (Resharper) on the style names contained in these resources.
Now, the application also implements a "plug-in" architecture, and there are several class library projects containing views and view models; these get dynamically loaded at runtime. Although the application runs fine, I don't get style name intellisense when I edit XAML views in these projects. I can get the intellisense to work by merging the necessary styles into a view's XAML, e.g.:-
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/foo.Client.Common;component/UIStyles/Buttons.xaml" />
//etc..
</ResourceDictionary.MergedDictionaries>
// User control-specific styles go here.
</ResourceDictionary>
</UserControl.Resources>
By doing this in each user control, am I "duplicating" each resource and therefore bloating the application's memory requirements? If so, is there any way around it? What if I created a resource file in the class library, merged the 15 "core" resources into that, then merged this one resource into my views? Will it still result in the same issue?
Failing this I guess I'll have to keep the "merge XAML" commented out in each view, and temporarily reinstate it only when I need to work on a view.
Good question. I have the same problem.
There are essentially two problems here:
1) Annoying duplication in the Xaml code - I am not talking about the duplication of actual resources - rather, you have to write <ResourceDictionary> everywhere.
2) The actual duplication of resources - wasting resources, plus: you will lose the benefit of swapping out the styles on runtime, if they are not placed in the same place.
HOw can you solve these problems?
By creating new xaml file, calling it SharedResourceDictionary.xaml, which includes all the resources. This will be included by App.xaml.
This will essentially allow you to pull the ResourceDictionary inside other xaml components, in a short way, just include the SharedResourceDictionary.xaml.
The second trick is to make sure the resources are created only once:
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation",
"WPFTutorial.Utils")]
/// <summary>
/// The shared resource dictionary is a specialized resource dictionary
/// that loads it content only once. If a second instance with the same source
/// is created, it only merges the resources from the cache.
/// </summary>
public class SharedResourceDictionary : ResourceDictionary
{
/// <summary>
/// Internal cache of loaded dictionaries
/// </summary>
public static Dictionary<Uri, ResourceDictionary> _sharedDictionaries =
new Dictionary<Uri, ResourceDictionary>();
/// <summary>
/// Local member of the source uri
/// </summary>
private Uri _sourceUri;
/// <summary>
/// Gets or sets the uniform resource identifier (URI) to load resources from.
/// </summary>
public new Uri Source
{
get { return _sourceUri; }
set
{
_sourceUri = value;
if (!_sharedDictionaries.ContainsKey(value))
{
// If the dictionary is not yet loaded, load it by setting
// the source of the base class
base.Source = value;
// add it to the cache
_sharedDictionaries.Add(value, this);
}
else
{
// If the dictionary is already loaded, get it from the cache
MergedDictionaries.Add(_sharedDictionaries[value]);
}
}
}
}
If that doesn't work, there's some comments below: http://www.wpftutorial.net/MergedDictionaryPerformance.html
It's also possible to explore the land of xaml ifdef code:
Does XAML have a conditional compiler directive for debug mode?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With