if you worked on some larger wpf applications you might be familiar with this. Because ResourceDictionaries are always instantiated, everytime they are found in an XAML we m
I am not quite sure if this will solve your issue. But I had similar issues with ResourceDictionary
referencing controls and its to do with lazy hydration. Here is a post on it. And this code resolved my issues:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
WalkDictionary(this.Resources);
base.OnStartup(e);
}
private static void WalkDictionary(ResourceDictionary resources)
{
foreach (DictionaryEntry entry in resources)
{
}
foreach (ResourceDictionary rd in resources.MergedDictionaries)
WalkDictionary(rd);
}
}
I'm running into the same issue of needing shared resource directories in a large-ish WPF project. Reading the source article and the comments, I incorporated a couple fixes to the SharedDirectory class as suggested in the comments, which seem to have removed the strong reference (stored in _sourceUri) and also make the designer work correctly. I tested your example and it works, both in the designer and MemProfiler successfully noting no held references. I'd love to know if anyone has improved it further, but this is what i'm going with for now:
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 {
if (IsInDesignMode)
return base.Source;
return _sourceUri;
}
set
{
if (IsInDesignMode)
{
try
{
_sourceUri = new Uri(value.OriginalString);
}
catch
{
// do nothing?
}
return;
}
try
{
_sourceUri = new Uri(value.OriginalString);
}
catch
{
// do nothing?
}
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]);
}
}
}
private static bool IsInDesignMode
{
get
{
return (bool)DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty,
typeof(DependencyObject)).Metadata.DefaultValue;
}
}
}