WPF 博士有几个建议:
http ://drwpf.com/blog/2007/10/05/managing-application-resources-when-wpf-is-hosted/
下面引用一些相关部分:
在代码中创建应用程序实例并添加资源
下面是一个非常简单的函数,如果应用程序对象不存在,它将创建它,然后加载一些资源:
public static void EnsureApplicationResources()
{
if (Application.Current == null)
{
// create the Application object
new Application();
// merge in your application resources
Application.Current.Resources.MergedDictionaries.Add(
Application.LoadComponent(
new Uri("MyLibrary;component/Resources/MyResourceDictionary.xaml",
UriKind.Relative)) as ResourceDictionary);
}
}
现在,您只需确保在解析任何包含对应用程序级资源的静态资源引用的 XAML 文件之前调用此函数。为此,只需在基于标记的类的构造函数中添加对上述函数的调用,然后再调用InitializeComponent()
:
public Page1()
{
EnsureApplicationResources();
InitializeComponent();
}
在 XAML 中定义应用程序类并动态创建它
首先,我们不希望 MSBuild 为我们的应用程序类生成应用程序入口点。因此,我们需要将其声明为元素,而不是将文件声明为项目文件中的App.xaml
元素:ApplicationDefinition
Page
<Page Include="App.xaml" />
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
接下来,我们需要确保我们的App.xaml
标记被解析。通常,这是作为入口点函数的一部分完成的(我们刚刚删除了它)。相反,我们可以简单地为Application
类定义一个构造函数并直接调用InitializeComponent
:
public App()
{
InitializeComponent();
}
现在我们所有的资源和合并的字典都可以在其中声明App.xaml
,我们加载应用程序实例的静态函数可以像这样简单:
public static void EnsureApplicationResources()
{
if (Application.Current == null)
{
// create the Application object
new App();
}
}
在代码中管理资源字典的集合并在元素级别合并它们
在这种情况下,我们根本不利用Application
对象。相反,我们在运行时动态加载每一个ResourceDictionary
,并根据需要有选择地将其合并到页面或窗口或特定元素中。
public static class SharedResources
{
public static readonly DependencyProperty MergedDictionariesProperty =
DependencyProperty.RegisterAttached("MergedDictionaries",
typeof(string), typeof(SharedResources),
new FrameworkPropertyMetadata((string)null,
new PropertyChangedCallback(OnMergedDictionariesChanged)));
public static string GetMergedDictionaries(DependencyObject d)
{
return (string)d.GetValue(MergedDictionariesProperty);
}
public static void SetMergedDictionaries(DependencyObject d, string value)
{
d.SetValue(MergedDictionariesProperty, value);
}
private static void OnMergedDictionariesChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
if (!string.IsNullOrEmpty(e.NewValue as string))
{
foreach (string dictionaryName in (e.NewValue as string).Split(';'))
{
ResourceDictionary dictionary = GetResourceDictionary(dictionaryName);
if (dictionary != null)
{
if (d is FrameworkElement)
{
(d as FrameworkElement).Resources
.MergedDictionaries.Add(dictionary);
}
else if (d is FrameworkContentElement)
{
(d as FrameworkContentElement).Resources
.MergedDictionaries.Add(dictionary);
}
}
}
}
}
private static ResourceDictionary GetResourceDictionary(string dictionaryName)
{
ResourceDictionary result = null;
if (_sharedDictionaries.ContainsKey(dictionaryName))
{
result = _sharedDictionaries[dictionaryName].Target;
}
if (result == null)
{
string assemblyName = System.IO.Path.GetFileNameWithoutExtension(
Assembly.GetExecutingAssembly().ManifestModule.Name);
result = Application.LoadComponent(new Uri(assemblyName
+ ";component/Resources/" + dictionaryName + ".xaml",
UriKind.Relative)) as ResourceDictionary;
_sharedDictionaries[dictionaryName] = new WeakReference(result);
}
return result;
}
private static Dictionary<string, WeakReference> _sharedDictionaries
= new Dictionary<string, WeakReference>();
}
这将允许我们将共享资源字典合并到任何框架元素的 Resources 集合中,只需执行以下操作:
<Grid dw:SharedResources.MergedDictionaries="ApplicationBrushes;ButtonStyles">