I moved some of my resources which are commonly used to a ResourceDictionary, example
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="SaveButtonStyle" TargetType="{x:Type Button}">
<Setter Property="IsDefault" Value="True" />
<Setter Property="IsCancel" Value="False" />
<Setter Property="ToolTip" Value="Close and save any changes you have made." />
</Style>
<Style x:Key="CloseButtonStyle" BasedOn="{StaticResource XSaveCloseButtonStyle}" TargetType="{x:Type Button}">
<Setter Property="IsDefault" Value="False" />
<Setter Property="IsCancel" Value="True" />
<Setter Property="ToolTip" Value="Close window." />
</Style>
</ResourceDictionary>
The reason for this is simple, I need the same styles in multiple places. But there is a problem I found, if somewhere I need to use CloseButtonStyle only, and I reference this resource dictionary. I think it creates both styles, I did a little test and on the code behind I looked by method FindResource to see whether I’ll get an instance of each style and I did. So my question is how do I deal with this? I don’t want to create 2 objects if I only need one, but I also don’t want to write this styles by copying and pasting it in many places.
You could do the following:
ResourcesHolder class contains Dictionary where parsed objects are stored. To, if any resource had already been parsed, you will return it from this dictionary:
private Dictionary<string, object> storedObjects;
public object FindResource(string resourceName)
{
if (storedObjects.ContainsKey(resourceName))
return storedObjects[resourceName];
else
//search, parse and return new resource
}
So, you can load every resource individually without loading anything else
EDIT:
Before calling Initialize() method you could load all the resources that you will need to create your window/usercontrol. In this case, you could add method to ResourceHolder:
public void Load(string resourceName)
{
if (Application.Current.Resources.Contains(resourceName))
return;
else
{
var obj = /*load your resource here*/;
Application.Current.Resources.Add(resourceName, obj)
}
}
And in your control/window:
public partial class TestWindow : Window
{
public TestWindow()
{
ResourceHolder.Load("SaveButtonStyle");
ResourceHolder.Load("CloseButtonStyle");
InitializeComponent();
}
}
In this case in your xaml you can use {StaticResource} extension
If you want do it automatically in xaml like {StaticResource} or {DynamicResource}, you will have to write your own markupextension that would call Load or FindResource method of ResourceHolder itself