【问题标题】:App.xaml file does not get parsed if my app does not set a StartupUri?如果我的应用程序未设置 StartupUri,则不会解析 App.xaml 文件?
【发布时间】:2009-02-12 21:37:15
【问题描述】:

背景:我正在使用 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 中挂钩OnStartup 来创建MainWindow,如下所示:

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

问题是,应用程序在尝试显示窗口时崩溃,但有以下例外:

找不到名为“{serviceLocator}”的资源。资源名称区分大小写。标记文件“WpfApp;component/mainwindow.xaml”第 8 行位置 45 中的对象“System.Windows.Data.Binding”出错。

据我所知,&lt;Application.Resources&gt; 部分根本没有从 xaml 文件中读出。我可以在 OnStartup 中添加一些代码,像这样以编程方式添加资源:

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

但是,这是一个丑陋的 hack,如果我以后想在 app.xaml 文件中添加其他内容,这对我没有帮助:-(

我应该挂钩其他事件吗?有没有办法解决这个问题?

【问题讨论】:

    标签: wpf xaml resources startup


    【解决方案1】:

    不要覆盖 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();
        }
    }
    

    【讨论】:

    • 为什么从 xaml 设置事件很重要?如果从构造函数设置它会失败...
    • 请注意,PRISM 应用程序默认存在此问题。通过添加空事件Application_Startup解决。
    【解决方案2】:

    最简单的解决方法是定义 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

    【讨论】:

    【解决方案3】:

    我遇到了类似/同样的问题。有一个 VS 代码生成错误,当&lt;Application.Resources&gt; 仅包含一个条目且没有StartupUri 属性时,有时不会插入将&lt;Application.Resources&gt; 连接到程序其余部分所需的代码。

    详情: http://bengribaudo.com/blog/2010/08/19/106/bug-single-application-resources-entry-ignored(免责声明——链接指向我的博客)

    【讨论】:

    • Visual Studio 2015 仍然存在错误 :-( 我生命中的另外三个小时已经过去了。
    • 这个错误有时会发生在我在 VS 2017 中开发的应用程序的生产中。所以看起来这个错误仍然存​​在。
    • 2020 年末,问题仍然存在。
    【解决方案4】:

    要解决这个已知错误,您还可以通过编程方式添加资源。

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

    此代码可以放在 App 类的构造函数中。

    【讨论】:

      猜你喜欢
      • 2010-10-16
      • 1970-01-01
      • 2014-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-25
      • 2023-03-16
      相关资源
      最近更新 更多