46

背景:我正在使用 MVVM 创建一个 WPF 应用程序,并使用 DI 容器来构建我的 ViewModels

我的 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”第 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

我遇到了类似/同样的问题。有一个 VS 代码生成错误,当仅包含一个条目且没有属性<Application.Resources>时,有时不会插入连接到程序其余部分所需的代码。<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 回答