查找资源字典的设计时错误 - 项目之间不一致 [英] Design-time Error finding the Resource Dictionary - Inconsistent between projects

查看:70
本文介绍了查找资源字典的设计时错误 - 项目之间不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TLDR;

屏幕新引用 VS2015 样式的外部 ResourceDictionary 文件在运行时正确,但不是在设计时.什么给?

<小时>

在工作中,我们有一个 WinForms 产品,其中包含 许多 WinForms 屏幕,其中一名开发人员积极添加新的屏幕,以及少数 WPF 屏幕,我添加了新的屏幕.注意到现有 WPF 屏幕中有很多重复的代码/样式,我创建了一个项目来容纳它 - 所有现有/未来的 WPF 屏幕都可以引用.

项目:WpfHelper

  • 平台目标:任何 CPU
  • 目标框架:.NET Framework 4.6
  • WpfHelper.dll 部署到 ...\Trunk\Project\Externals
  • ...\Trunk\Utilities\WpfHelper\WpfHelper\Resources\GlobalResources.xaml
    • 构建操作:页面
    • ResourceDictionary 包含通用样式
<小时>

我在六个项目中引用了...\Trunk\Project\Externals\WpfHelper.dll,将以下代码添加到它们的每个资源文件中:

<ResourceDictionary Source="pack://application:,,,/WpfHelper;Component/Resources/GlobalResources.xaml"/></ResourceDictionary.MergedDictionaries>

所有屏幕都位于...\Trunk\Project\Plugins.

╔=========╦================╦================╦==================╦======================================================================================================================╗║ ║ 资源作品?║ 平台目标 ║ 目标框架 ║ 参考文件路径 ║╠=========╬================╬===============╬==================╬==================================================================================================================================╣║ Project1 ║ 成功 ║ 任何 CPU ║ .NET 4.6 ║ ...\Project1\Project1\Resources\Resources.xaml ║║ Project2 ║ 成功 ║ x86 ║ .NET 4.6 ║ ...\Project2\Project2\Resources\Resources.xaml ║║ Project3 ║ 成功 ║ 任何 CPU ║ .NET 4.6 ║ ...\Project3\Project3\Resources\Resources.xaml ║║ Project4 ║ 失败 ║ x86 ║ .NET 4.6 ║ ...\Project4\Project4\Resources\Resources.xaml ║║ Project5 ║ 失败 ║ x86 ║ .NET 4.6 ║ ...\Project5\Project5\Resources\Resources.xaml ║║ Project6 ║ 失败 ║ 任何 CPU ║ .NET 4.6 ║ ...\Project6\Project6\Resources\Resources.xaml ║╚=========╩===============╩===============╩==================╩================================================================================================================================╝

最近的变化

最近我将 Visual Studios 2013 升级到 2015.大约在同一时间,另一位屏幕开发人员将所有现有屏幕项目的目标框架从 .NET Framework 3.5/4.0 升级到 .NET Framework 4.6.

成功的项目

  • 我在最近更改之前引用了WpfHelper.dll.
  • 在设计时和运行时正确应用样式.

失败的项目

  • 我在最近更改之后引用了WpfHelper.dll.
  • 仅在运行时正确应用样式.
  • 在设计时,抛出错误:<块引用>

    查找资源字典pack://application,,,/WpfHelper;component/Resources/GlobalResources.xaml"时出错.

  • 使用本地Resources.xaml的地方,抛出后续错误:<块引用>

    值不能为空.参数名称:item

我尝试过的:

阅读大量文章和问答后:

我尝试了以下所有方法均无济于事:

  • 将项目平台目标更改为任何 CPU"
  • 将项目目标框架从 .NET Framework 4.6 更改为/更改为 .NET Framework 4.6
  • 确保所有 Resource.xaml 文件具有相同的构建操作(页面)等.
  • 检查每个项目的 AssemblyInfo.cs 文件.失败的项目包括(我删除了)以下内容:

    [程序集:ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]

  • 手动清除 AppsData 中的临时文件夹,已清理并重建项目.

  • 重新打开的项目.
  • 重新启动.
  • 右键单击从工作项目中复制的 WpfHelper.dll 引用并粘贴到失败项目的引用中.
  • WpfHelper.Resources.GlobalResources.xaml 作为链接文件添加到失败的项目中.
  • 唠叨每个同事.
  • GlobalResources.xaml 中使用的子词典添加了完整的包 URI.
  • 杀死设计师并重建项目.

我没有想法并且迷失在研究中.我已经模板化其中一种可行的解决方案,并将其用于创建新屏幕 - 创建在设计时成功显示的新屏幕-时间.这与这些预先存在的屏幕有关.如何让失败的项目在设计时正确显示样式资源?

解决方案

我已经为这个问题制定了一个解决方案,而且实施起来并不费力.

首先为资源字典添加一个代码隐藏文件,GlobalResources.xaml.cs:

namespace YourNamespaceHere{部分类 GlobalResources : ResourceDictionary{公共全球资源(){初始化组件();}}}

然后将 x:Class 属性设置为 GlobalResources.xaml 中的 ResourceDictionary 标记:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"x:Class="YourNamespaceHere.GlobalResources">

您现在可以像这样创建资源字典的实例:

new YourNamespaceHere.GlobalResources()

在使用资源字典的 WPF 用户控件中,将以下内容添加到构造函数 i UserControl1.xaml.cs 中:

public UserControl1(){如果 (DesignerProperties.GetIsInDesignMode(this))this.Resources.MergedDictionaries.Add(new YourNamespaceHere.GlobalResources());初始化组件();}

现在,使用 UserControl1 的控件的 WinForms 设计器将不再抱怨找不到包含资源字典的 dll.使用的资源也会显示在设计器中.

为了确保 WPF 设计器将显示 UserControl1 中使用的资源字典中的内容,您的 UserControl1.xaml 中仍需要以下内容:

<资源字典><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="pack://application:,,,/MyDll;component/GlobalResources.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary></UserControl.Resources>

MyDll 是包含资源字典的程序集的名称.在此示例中,GlobalResources.xaml 和 GlobalResources.xaml.cs 应放置在程序集的根级别(而不是文件夹中).

TLDR;

Screens newly referencing an external ResourceDictionary file in VS2015 style correctly at run-time, but not at design-time. What gives?


At work, we have a WinForms product which houses many WinForms screens with one developer actively adding new ones, as well as a handful of WPF screens with me adding new ones. Noticing a lot repetitious code/styling in existing WPF screens, I created a single project to house this - to be referenced by all existing/future WPF screens.

Project: WpfHelper

  • Platform target: Any CPU
  • Target framework: .NET Framework 4.6
  • WpfHelper.dll deployed to ...\Trunk\Project\Externals
  • ...\Trunk\Utilities\WpfHelper\WpfHelper\Resources\GlobalResources.xaml
    • Build Action: Page
    • ResourceDictionary containing generic styles

I have referenced ...\Trunk\Project\Externals\WpfHelper.dll in six projects, adding the following code to each of their resource files:

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="pack://application:,,,/WpfHelper;Component/Resources/GlobalResources.xaml" />
</ResourceDictionary.MergedDictionaries>

All screens are located in ...\Trunk\Project\Plugins.

╔══════════╦═════════════════╦═════════════════╦══════════════════╦════════════════════════════════════════════════╗
║          ║ Resource Works? ║ Platform Target ║ Target Framework ║ Reference File Path                            ║
╠══════════╬═════════════════╬═════════════════╬══════════════════╬════════════════════════════════════════════════╣
║ Project1 ║ Succeeded       ║ Any CPU         ║ .NET 4.6         ║ ...\Project1\Project1\Resources\Resources.xaml ║
║ Project2 ║ Succeeded       ║ x86             ║ .NET 4.6         ║ ...\Project2\Project2\Resources\Resources.xaml ║
║ Project3 ║ Succeeded       ║ Any CPU         ║ .NET 4.6         ║ ...\Project3\Project3\Resources\Resources.xaml ║
║ Project4 ║ Failed          ║ x86             ║ .NET 4.6         ║ ...\Project4\Project4\Resources\Resources.xaml ║
║ Project5 ║ Failed          ║ x86             ║ .NET 4.6         ║ ...\Project5\Project5\Resources\Resources.xaml ║
║ Project6 ║ Failed          ║ Any CPU         ║ .NET 4.6         ║ ...\Project6\Project6\Resources\Resources.xaml ║
╚══════════╩═════════════════╩═════════════════╩══════════════════╩════════════════════════════════════════════════╝

Recent Changes

Just recently I upgraded Visual Studios 2013 to 2015. Around the same time, the other screen developer upgraded all existing screen project's target frameworks to .NET Framework 4.6 from .NET Framework 3.5/4.0.

Successful Projects

  • I referenced WpfHelper.dll prior to the Recent Changes.
  • Styles applied correctly at Design-time and Run-time.

Failed Projects

  • I referenced WpfHelper.dll after the Recent Changes.
  • Styles applied correctly at Run-time only.
  • During Design-time, the error is thrown:

    An error occurred while finding the resource dictionary "pack://application,,,/WpfHelper;component/Resources/GlobalResources.xaml".

  • Where the local Resources.xaml are used, the subsequent error is thrown:

    Value cannot be null. Parameter name: item

What I have tried:

After reading an extensive list of articles and Q&A's:

I tried all the following to no avail:

  • Change project Platform target to "Any CPU"
  • Change project Target framework from/to .NET Framework 4.6
  • Ensure all Resource.xaml files had the same Build Action (Page), etc.
  • Checked each project's AssemblyInfo.cs file. Failing projects included (and I removed) the following:

    [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
    

  • Manually cleared the temp folder in AppsData, Cleaned & Rebuilt projects.

  • Re-opened projects.
  • Rebooted.
  • Right-click copied WpfHelper.dll references from working projects and pasted into references of failing projects.
  • Added the WpfHelper.Resources.GlobalResources.xaml as a Linked file to the failed projects.
  • Nagged every co-worker.
  • Added the full pack URI for sub-dictionaries used in GlobalResources.xaml.
  • Killed the designer and rebuilt the project.

I'm out of ideas and lost in research. I've templated one of the working solutions and used that for creating new screens - that creates new screens which successfully display at design-time. It's something about these pre-existing screens. How can I get the failed projects to correctly display styled resources at design-time?

解决方案

I have worked out a solution to this problem that takes little effort to implement.

First add a code behind file for the resource dictionary, GlobalResources.xaml.cs:

namespace YourNamespaceHere
{
    partial class GlobalResources : ResourceDictionary
    {
        public GlobalResources()
        {
            InitializeComponent();
        }
    }
}

Then set the x:Class property to the ResourceDictionary tag in GlobalResources.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    x:Class="YourNamespaceHere.GlobalResources">

You are now able to create an instance of the resource dictionary like this:

new YourNamespaceHere.GlobalResources()

In the WPF user control where you are using the resource dictionary, add the following to the constructor i UserControl1.xaml.cs:

public UserControl1()
{
    if (DesignerProperties.GetIsInDesignMode(this))
        this.Resources.MergedDictionaries.Add(new YourNamespaceHere.GlobalResources());

    InitializeComponent();
}

Now the WinForms designer for the control where UserControl1 is used, will no longer complain about not finding your dll containing the resource dictionary. Used resources will also be displayed in the designer.

To make sure the WPF designer will show content from the resource dictionary that is used in UserControl1, you still need the following in your UserControl1.xaml:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/MyDll;component/GlobalResources.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

MyDll is the name of the assembly containing the resource dictionary. In this example GlobalResources.xaml and GlobalResources.xaml.cs are expected to be placed at the root level of the assembly (not in a folder).

这篇关于查找资源字典的设计时错误 - 项目之间不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆