XAML(WPF)设计器无法以一致或有意义的方式解析应用程序资源

时间:2017-05-27 16:23:53

标签: c# wpf xaml

我经常受到设计师问题的困扰,XAML设计师(WPF' xdesproc")将以一种方式显示我的控件,但它们将以完全不同的方式显示在运行时的方式。这些差异通常归结为运行时使用的静态资源(在应用程序级别)不是设计器中使用的静态资源。

这主要发生在大型解决方案由多个项目组成时 - 其中大多数是用户控制库,其中一些是启动项目(应用程序,测试工具等)。

在使用VS编辑其中一个库中的用户控件时,我发现了Blend的一个技巧,你可以引入" DesignTimeResources.xaml"文件在一个项目和视觉工作室将"尊重"并将这些资源合并为用户控件本身的补充(就好像它们已在该用户控件的逻辑树中找到)。

我认为这个技巧足以让我能够放弃设计师对应用程序级资源的需求。然而," DesignTimeResources.xaml"并没有解决我所有的问题。 xdesproc也不认为这是应用程序级资源的充足来源(即xdesproc可能会考虑将此两者作为其应用程序级资源加载到逻辑树中。用户控制是否需要。)

在使用procmon窥探xdesproc之后,我发现它以非常不寻常的方式运行,以便找到它想要用于其应用程序级资源的内容。它使用的搜索机制 not 似乎非常明确。如果一个人不小心,它要么忽略了建立任何应用程序级资源,要么从它可能在外部解决方案中找到的一个项目中随机选择(一个可能不相关的项目)以任何方式访问usercontrol库,但是找到并使用它,因为它包含一个恰好是" Application /")的项目项。

有人可以告诉我,在编辑用户控件时,是否应该有一个明确定义的方式xdesproc找到应用程序级资源?我的解决方法是涉及卸载项目的大量强迫性修补。我暂时从我的解决方案中卸载所有项目,其中包含" Application"元素,除了一个。除非我这样做,否则xdesproc可能会随机选择其中一个,并开始愉快地将其用于其应用级资源。它似乎并不局限于VS IDE中的当前启动项目。

我很感激任何指示,以帮助我理解xdesproc认为它应该用于其应用资源的内容。我怀疑它被编程为" smart"和#34;只是工作"。它可能在许多情况下都有效,除非它没有。

3 个答案:

答案 0 :(得分:2)

这是我经过多次试错后发现的。在编辑库中的用户控件时,设计人员将扫描整个解决方案,并尝试根据许多复杂条件为您查找应用程序级资源。搜索并不像我最初认为的那么随机。它只会找到并使用资源:

  • 在未卸载的项目中,输出类型为“Windows Application”
  • 资源必须包含在项目中的“Application”成员中(System.Windows.Application)
  • 此成员的构建操作必须是“ApplicationDefinition”(即,您无法将构建操作设置为“Page”并与单独的静态Main相结合)
  • 必须存在指向您正在使用的usercontrol库的直接项目引用。
  • 如果/当有多个候选符合上述条件时,设计人员将使用配置为当前启动项目的那个。

考虑到设计人员在其应用程序级资源中搜索某些内容的程度和范围,有一些令人遗憾的后果会以实际方式影响开发人员:

  • 如果您正在使用的usercontrol库包含本地“DesignTimeResources.xaml”,您可能会合理地认为这些将由设计人员使用,并且他们将“胜过”扫描解决方案时在其他地方找到的任何应用程序定义。不幸的是反过来也是如此。设计人员会喜欢它在(松散)相关项目中找到的应用程序级资源(即,在引用usercontrol库作为其依赖项之一的项目中)。它将完全IGNORE你的usercontrol库中的“DesignTimeResources.xaml”字典。如果在整个解决方案中找不到其他资源候选者,它将仅使用“DesignTimeResources.xaml”作为最后的手段。
  • 作为开发人员的另一个后果是,如果您有许多项目符合设计师用于选择其应用程序级资源的标准,那么您最终会感到非常困惑。我的解决方案通常包含许多简单的测试工具。它们是小型启动项目,每个项目都有一个应用程序定义,不一定具有完美的静态资源集。事实上,任何给定的测试工具通常都有一个最差的应用程序级资源示例,因为它的资源只与完整应用程序的一个子集相关。但是,这些简单的测试工具通常最终会被设计师选择在扫描解决方案时使用它的应用程序级资源;这可能会导致意想不到的后果。同样,当在各种测试工具之间切换当前启动项目时,它会显着影响和破坏设计人员将使用的应用程序级资源集。

为了克服这些实际问题,我通常最终会卸载所有项目候选项,否则设计师就会找到这些项目。这迫使设计者依赖于usercontrol库本身的本地“DesignTimeResources.xaml”。或者,您可以卸载所有当前用作启动的单个项目...但只需确保查看其资源,并且它们可在运行时使用供编辑者在编辑控件时使用。

对于我来说,WPF设计师(“xdesproc”)如何以随意且定义不明确的方式搜索整个解决方案似乎有点吓人。我怀疑我不是唯一被我的应用程序资源相关的WPF设计师问题“咬”的人。我从来没有在互联网上发现很多设计师应该如何发现应用程序级资源。也许事情是故意模糊的,以便行为可以随着时间的推移而改变。虽然我注意到有人最近报告了与“DesignTimeResources.xaml”相关的VS 2017错误,但至少这不是一个不常见的东西。

希望当您遇到难以解释的设计师问题时,此信息将会有所帮助。如果您观察到的行为与我在尝试VS 2017时的行为不同,请发表评论。

答案 1 :(得分:1)

为了解决这类问题,我没有使用“DesignTimeResources.xaml”(我不知道这是一个东西)。

当我有我想使用设计器的带有控件的程序集时,我在根目录中创建 App.xaml(和 App.xaml.cs)(例如,从启动程序集复制)。我将 BuildAction 设置为“页面”。

在 App.xaml 中,我引用了使用程序集时预期加载的资源。

我们有一些菊花链程序集,因此每个带有控件的程序集都有一个“AllDictionaries.xaml”资源字典,可供使用它的程序集引用。

App.xaml 内容示例:

<Application x:Class="RD.Controls.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/RD.Controls;component/AllDictionaries.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

在程序集中拥有 App.xaml 文件可确保加载“主字典”,该字典从引用程序集中引用任何其他所需资源。

答案 2 :(得分:0)

我对这个话题有更多的答案(来自我以外的人)。这是来自Visual Studio开发人员社区的Microsoft工程师......

见链接:

https://developercommunity.visualstudio.com/content/problem/86265/xamlwpf-designer-will-not-find-application-resourc.html

  

我快速查看了查找应用程序文档的逻辑。   您对StackOverflow的描述似乎很准确。我总结一下   设计师的偏好顺序为:

     

1.包含打开的XAML文件的项目中的应用程序文档。

     

2.启动项目的应用文档

     

3.我们发现的第一个项目中的应用程序文档引用了包含打开的XAML文件的项目。

     

没有设计师功能告诉用户哪个应用程序文档   我们选择了。我们通常假设将使用#1或#2   这是大多数用户想要的。我能理解,击中#3会   在复杂的解决方案中导致不可预测的结果。

相关问题