【问题标题】:XAML (WPF) designer does not resolve app resources in a consistent or meaningful wayXAML (WPF) 设计器未以一致或有意义的方式解析应用资源
【发布时间】:2023-03-27 11:05:01
【问题描述】:

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

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

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

我认为这个技巧就足够了,这样我就可以放弃设计器中对应用程序级资源的需求。但是,“DesignTimeResources.xaml”并不能解决我所有的问题。 xdesproc 也不认为这是足够的应用程序级资源来源(即 xdesproc 可能会考虑将此 both 作为其应用程序级资源 and 加载到如果需要,用户可以控制。)

在使用 procmon 窥探 xdesproc 后,我发现它以非常不寻常的方式运行,以便找到它想要用于其 应用程序级 资源的东西。它使用的搜索机制确实看起来非常明确。如果一个人不小心,它要么完全忽略建立任何应用程序级资源,要么从它可能在外部解决方案中找到的项目之一中随机选择(一个可能不相关的项目)以任何方式到用户控件库,但被发现并被使用是因为它包含一个恰好是“应用程序/”的项目项。

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

如果有任何指针可以帮助我理解 xdesproc 认为它应该用于其应用程序资源的内容,我将不胜感激。我怀疑它被编程为“智能”和“正常工作”。它可能在许多情况下都有效,除非它不起作用。

【问题讨论】:

    标签: c# wpf xaml


    【解决方案1】:

    这是我经过多次反复试验后发现的。当您在库中编辑用户控件时,设计器将扫描整个解决方案,并尝试根据一些复杂的标准为您查找应用程序级资源。搜索并不像我最初认为的那样随机。它只会在以下情况下查找和使用资源:

    • 在未卸载且输出类型为“Windows 应用程序”的项目中
    • 资源必须包含在项目 (System.Windows.Application) 的“应用程序”成员中
    • 此成员的构建操作必须是“ApplicationDefinition”(即,您不能将构建操作设置为“Page”并结合单独的静态 Main)
    • 必须存在指向您正在处理的用户控件库的直接项目引用。
    • 如果/当有 多个 候选者满足上述条件,则设计者将使用配置为当前启动项目的候选者。

    考虑到设计人员搜索应用程序级资源的范围和范围,有一些不幸的后果会以实际的方式影响开发人员:

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

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

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

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

    【讨论】:

      【解决方案2】:

      我对这个话题有更多的答案(来自我以外的其他人)。这是来自 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会 在复杂的解决方案中导致不可预测的结果。

      【讨论】:

        【解决方案3】:

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

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

        在 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 文件可确保加载“主字典”,它从引用程序集中引用任何其他需要的资源。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-01
          • 1970-01-01
          相关资源
          最近更新 更多