设计时错误查找资源字典 - 项目之间不一致

时间:2015-12-08 21:49:15

标签: c# wpf visual-studio-2015 resourcedictionary

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.MergedDictionaries>
    <ResourceDictionary Source="pack://application:,,,/WpfHelper;Component/Resources/GlobalResources.xaml" />
</ResourceDictionary.MergedDictionaries>

所有屏幕都位于...\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 ║
╚══════════╩═════════════════╩═════════════════╩══════════════════╩════════════════════════════════════════════════╝

最近的更改

就在最近,我将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

我尝试了什么:

阅读了大量文章和Q&amp; A之后:

我尝试了以下所有内容无济于事:

  • 将项目平台目标更改为“任何CPU”
  • 将项目目标框架从/向.NET Framework 4.6更改
  • 确保所有Resource.xaml文件具有相同的Build Action(Page)等。
  • 检查每个项目的AssemblyInfo.cs文件。失败的项目包括(并删除)以下内容:

    [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
    
  • 手动清除AppsData中的临时文件夹,已清除&amp;重建项目。

  • 重新开放项目。
  • 后重新启动。
  • 右键单击工作项目中复制的WpfHelper.dll引用,并粘贴到失败项目的引用中。
  • WpfHelper.Resources.GlobalResources.xaml添加为失败项目的链接文件。
  • 每个同事都被唠叨。
  • GlobalResources.xaml中使用的子词典添加了完整包URI。
  • Killed the designer并重建了该项目。

我出于想法而迷失在研究中。我templated有一个工作解决方案,用于创建新屏幕 - 创建新屏幕,在设计时成功显示。这是关于这些预先存在的屏幕的东西。如何让失败的项目在设计时正确显示样式化资源?

1 个答案:

答案 0 :(得分:2)

我已经找到了解决这个问题的方法,但是很难实现。

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

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

然后将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()
{
    if (DesignerProperties.GetIsInDesignMode(this))
        this.Resources.MergedDictionaries.Add(new YourNamespaceHere.GlobalResources());

    InitializeComponent();
}

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

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

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

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