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

11

简述;

在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时,会抛出以下错误:

    值不能为 null。 参数名: item

我尝试过的方法:

阅读了大量的文章和问答后:

我尝试了以下所有方法,但都无济于事:

  • 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.

我已经没有任何想法,也迷失在研究中。我已经模板化了一个可行的解决方案,并将其用于创建新屏幕 - 这样可以在设计时成功显示新屏幕。问题出在现有屏幕上。如何使失败的项目在设计时正确地显示样式资源?


你能解决这个问题吗? - Olga
很遗憾,这个问题从未得到解决。这使得修改有问题的屏幕的GUI变得更加耗时。 - OhBeWise
希望我能帮上忙。这是任何复杂项目的一个持续性问题。 - dex3703
@Olga,我们提供了一个新的解决方案。您能验证一下它是否适用于您吗? - OhBeWise
@OhBeWise 很抱歉,我现在无法测试这个答案。我正在处理另一个项目。如果我回到这个问题,我一定会测试这个答案。 - Olga
1个回答

3
我已经想出了一个解决这个问题的方案,实现起来很容易。
首先,为资源字典 GlobalResources.xaml 添加一个代码后台文件 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 用户控件中,在 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被放置在程序集的根级别(而不是文件夹中)。

我目前无法验证此解决方案是否有效 - 我换了工作,尝试重现问题的努力失败了。不过我有机会时会继续尝试。也许其他用户可以帮忙,@dex3703? - OhBeWise

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接