46

背景: 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 にハードコードされているため、これは望ましくありません。
見つけたいくつかのブログ投稿と記事のガイダンスに従って、 を削除し、次のように App.xaml.cs にフックしStartupUriて を作成しようとしました。MainWindowOnStartup

protected override void OnStartup( StartupEventArgs e )
{
    base.OnStartup(e);
    new MainWindow().Show();
}

問題は、次の例外を除いて、ウィンドウを表示しようとするとアプリがクラッシュすることです。

「{serviceLocator}」という名前のリソースが見つかりません。リソース名は大文字と小文字が区別されます。マークアップ ファイル 'WpfApp;component/mainwindow.xaml' の行 8 位置 45 のオブジェクト 'System.Windows.Data.Binding' でエラーが発生しました。

私が知る限り、この<Application.Resources>セクションは単に xaml ファイルから読み出されていません。OnStartup にコードを追加して、次のようにプログラムでリソースを追加できます。

Resources.BeginInit();
Resources.Add("serviceLocator", new ServiceLocator());
Resources.EndInit();

ただし、これは醜いハックであり、後で app.xaml ファイルに何か他のものを入れたい場合は役に立ちません :-(

他のイベントをフックする必要がありますか?これを回避する方法はありますか?

4

4 に答える 4

54

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();
    }
}
于 2009-02-17T02:01:12.240 に答える
26

最も簡単な回避策は、x:Nameの定義です。

<Application x:Name="App" ...
    <Application.Resources>
        ...
    </Application.Resources>
</Application>

詳細: http://connect.microsoft.com/VisualStudio/feedback/details/472729/wpf-cannot-find-resource-defined-in-the-app-xaml-file

于 2010-10-09T15:38:19.397 に答える
13

同様の/これと同じ問題に遭遇しました。エントリが 1 つしかなく、属性がない<Application.Resources>場合、プログラムの残りの部分に接続するために必要なコードが挿入されないことがある VS コード生成のバグがあります。<Application.Resources>StartupUri

詳細: http://bengribaudo.com/blog/2010/08/19/106/bug-single-application-resources-entry-ignored (免責事項 - リンク先は私のブログです)

于 2010-08-19T16:17:26.327 に答える
2

この既知のバグを回避するには、プログラムでリソースを追加することもできます。

var rd = new ResourceDictionary()
rd.Source = new Uri("pack://application:,,,/Resources;component/Colors.xaml");
Resources.MergedDictionaries.Add(rd);

このコードは、クラスのコンストラクター内に配置できますApp

于 2013-08-23T15:35:24.177 に答える