Reputation: 1270
I have used a custom class to implement shared resource functionality in my WPF application this is a sample code to create and manage dictionaries
public class SharedResourceDictionary : ResourceDictionary
{
/// <summary>
/// Internal cache of loaded dictionaries
/// </summary>
public static Dictionary<Uri, ResourceDictionary> SharedDictinaries = new Dictionary<Uri, ResourceDictionary>();
/// <summary>
/// Local member of the source uri
/// </summary>
private Uri _sourceUri;
private static bool IsInDesignMode
{
get
{
return (bool)DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty,
typeof(DependencyObject)).Metadata.DefaultValue;
}
}
/// <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)
{
base.Source = value;
return;
}
_sourceUri = value;
if (!SharedDictinaries.ContainsKey(value))
{
base.Source = value;
SharedDictinaries.Add(value, this);
}
else
{
MergedDictionaries.Add(SharedDictinaries[value]);
}
}
}
}
this File is implemented i a separate assembly and I have refferenced it in my shell WPF application.
I have my resources defined in app.xaml int the following way
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<Infrastructure:SharedResourceDictionary Source="pack://application:,,,/CuratioCMS.Client.Resources;Component/Themes/General/Brushes.xaml" />
<Infrastructure:SharedResourceDictionary Source="pack://application:,,,/Fluent;Component/Themes/Office2010/Silver.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
if I remove Brushes.xaml it works but with this dictinary in place as I switch to design view I get following error
Exception has been thrown by the target of an invocation
could someone help my to figure out the problem?
Upvotes: 2
Views: 7131
Reputation: 21
I know this issue is old and solved, but as I have been working on an alternative solution with a friend, I wanted to share it:
For more details see: https://github.com/hugener/Sundew.Xaml.Optimizations
And the sample:
https://github.com/hugener/Sundew.Xaml.Optimizer.Sample
Upvotes: 1
Reputation: 3361
To solve this problem I did (I really wanted to work at design time in VisualStudio 2010):
public string SourcePath { get; set; }
public new Uri Source
{
get
{
if (IsInDesignMode)
{
return base.Source;
}
else
{
return _sourceUri;
}
}
set
{
if (value == null)
return;
if (IsInDesignMode)
{
var dict = Application.LoadComponent(new Uri(SourcePath, UriKind.Relative)) as ResourceDictionary;
MergedDictionaries.Add(dict);
return;
}
_sourceUri = value;
if (!_sharedDictionaries.ContainsKey(value))
{
base.Source = value;
_sharedDictionaries.Add(value, this);
}
else
{
MergedDictionaries.Add(_sharedDictionaries[value]);
}
}
}
and in my XAML:
<SharedResourceDictionary SourcePath="JooThemes;component/Buttons/Small/SettingsToggleStyle.xaml" Source="/JooThemes;component/Buttons/Small/SettingsToggleStyle.xaml" />
Upvotes: 3
Reputation: 1080
I read somewhere, that it is a memory issue @design-time. I solved it in the Setter of Source:
/// <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))
{
try
{
//If the dictionary is not yet loaded, load it by setting
//the source of the base class
base.Source = value;
}
catch (Exception exp)
{
//only throw exception @runtime to avoid "Exception has been
//thrown by the target of an invocation."-Error@DesignTime
if( ! IsInDesignMode )
throw;
}
// 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]);
}
}
}
Upvotes: 0