Dr 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
、Application インスタンスをロードする静的関数は次のように単純になります。
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">