背景:MVVMを使用してWPFアプリを作成し、DIコンテナーを使用してViewModelを構築しています
私のApp.xamlは次のようになります。
<Application x:Class="WpfApp.App"
...xmlns etc...
StartupUri="MainWindow.xaml">
<Application.Resources>
<app:ServiceLocator x:Key="serviceLocator" />
</Application.Resources>
</Application>
MainWindow.xamlは次のようになります。
<Window x:Class="CompositeMefWpfApp.MainWindow"
...xmlns etc... >
<Control.DataContext>
<Binding Path="MainWindowViewModel" Source="{StaticResource serviceLocator}" />
</Control.DataContext>
これですべて正常に機能しますが、StartupUri
はXAMLにハードコードされているため、必要ありません。
見つけたいくつかのブログ投稿と記事のガイダンスに従って、StartupUri
を削除し、App.xaml.csでMainWindow
をフックしてOnStartup
を作成しようとしました。 、 このような:
protected override void OnStartup( StartupEventArgs e )
{
base.OnStartup(e);
new MainWindow().Show();
}
問題は、次の例外を除いて、ウィンドウを表示しようとするとアプリがクラッシュすることです。
'{serviceLocator}'という名前のリソースが見つかりません。リソース名では大文字と小文字が区別されます。マークアップファイル「WpfApp; component /mainwindow.xaml」のオブジェクト「System.Windows.Data.Binding」でエラーが発生しました。8行目位置45。
私の知る限り、<Application.Resources>
セクションがxamlファイルから読み取られていないだけです。 OnStartupにコードを入れて、次のようにプログラムでリソースを追加できます。
Resources.BeginInit();
Resources.Add("serviceLocator", new ServiceLocator());
Resources.EndInit();
ただし、これは醜いハックであり、後でapp.xamlファイルに何か他のものを入れたい場合は役に立ちません:-(
他のイベントをフックする必要がありますか?これを回避する方法はありますか?
OnStartupをオーバーライドするのではなく、代わりにイベントを使用してみてください。
<Application x:Class="My.App"
xmlns="..."
Startup="Application_Startup"
ShutdownMode="OnExplicitShutdown">
<Application.Resources>
<app:ServiceLocator x:Key="serviceLocator" />
</Application.Resources>
</Application>
背後にあるコード:
public partial class App : Application
{
public App()
{ }
private void Application_Startup(object sender, StartupEventArgs e)
{
// TODO: Parse commandline arguments and other startup work
new MainWindow().Show();
}
}
最も簡単な回避策は、x:Nameの定義です。
<Application x:Name="App" ...
<Application.Resources>
...
</Application.Resources>
</Application>
私は同様の/これと同じ問題に遭遇しました。 <Application.Resources>
にエントリが1つだけ含まれ、StartupUri
属性がない場合、<Application.Resources>
をプログラムの残りの部分に接続するために必要なコードが挿入されないことがあるVSコード生成のバグがあります。
詳細: http://bengribaudo.com/blog/2010/08/19/106/bug-single-application-resources-entry-ignored(免責事項- -リンクは私のブログを指しています)
この既知のバグを回避するには、プログラムでリソースを追加することもできます。
var rd = new ResourceDictionary()
rd.Source = new Uri("pack://application:,,,/Resources;component/Colors.xaml");
Resources.MergedDictionaries.Add(rd);
このコードは、App
クラスのコンストラクター内に配置できます。