wpf - 合并字典和资源查找

标签 wpf performance resourcedictionary staticresource mergeddictionaries

一般来说,我对资源字典和合并字典有问题,尤其是在资源查找性能方面。经过一些性能测试后,我发现 ResourceDictionary.get_MergedDictionaries 是点击次数最多的调用(在 ANTS 分析器中检查)。我们有大约 300 个资源字典 xamls,其中很多都使用合并字典来“包含”其他样式。好吧,get_MergedDictionaries 依赖于我们应用程序的一个部分,其中发生的事情不多,大约是 1000 万次点击。所以我的猜测是我们对 Resource 字典做的事情总体上是完全错误的。所以我试图重构一切,我想尝试摆脱所有合并的字典。

现在到实际问题。我试图摆脱合并词典,但我失败了。我的理解是,当您使用 StaticResource 时,查找需要在当前资源之前定义资源。我做了以下简短的例子:

一个主项目和一个自定义控件库。

自定义控件库包含 2 个 xaml。

<!-- Colors.xaml -->
<ResourceDictionary [stripped namespaces] >
    <SolidColorBrush x:Key="myColor" Color="Green"/>
</ResourceDictionary>

<!-- Templates.xaml -->
<ResourceDictionary [stripped namespaces]>
    <ControlTemplate x:Key="myTemplate" TargetType="Button">
        <Rectangle Fill="{StaticResource myColor}"/>
    </ControlTemplate>
</ResourceDictionary>

现在在主项目中,MainWindow.xaml 看起来像这样
<Window x:Class="ResourceTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/ResourceTestLib;component/Themes/Colors.xaml"/>
                <ResourceDictionary Source="/ResourceTestLib;component/Themes/Template.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Button Template="{StaticResource myTemplate}"/>
    </Grid>
</Window>

这就是期望的目标。但不幸的是,这会崩溃,因为找不到资源“myColor”。我当然知道如何修复它,在 Templates.xaml 中添加一个合并字典并引用 Colors.xaml 但我一直认为,我从来没有真正检查过,根据逻辑树和元素的资源查找资源。我的理解是;按钮已创建;尝试查找模板 .. 找到;尝试查找颜色,在自己的资源中找不到,走起来使用 windows 资源。

看来我错了。
所以我希望有人可以为我阐明这一点。我们大量使用 WPF,尽管如此,我们还是用它取得了很多成就,但是由于一开始的一些错误学习行为,我们的性能非常糟糕,因为资源查找。
任何帮助将不胜感激

提前致谢
此致
妮可

最佳答案

好吧,我不喜欢回答我自己的问题,但我想很多人可能会偶然发现这个问题,我想给他们我们当前的解决方案作为一个可供考虑的选项。
就像我之前说的,我们有很多 XAML,大约 300 个左右用于所有不同类型的东西,例如共享资源(画笔、颜色),还有许多包含不同数据模板、控件样式和自定义控件的 XAML。一开始,这种拥有大量 XAML 的方法对我们来说是合理的,因为我们对我们的类做同样的事情并保持它们小而有组织。
不幸的是,WPF 不喜欢那样。您拥有的 ResourceDictionaries 越多,并且通过 MergedDictionaries 合并它们的次数越多,您的性能就会越差。
我能给你的最好建议是,尽可能少地使用 ResourceDictionary XAML .
我们硬着头皮将其中的很多合并到一个巨大的 XAML 中,事实上,我们现在使用一个预编译器来做到这一点,同时保留了两全其美的优势。我们可以根据需要使用任意数量的 XAML,只需遵循一些约束,然后将它们合并到一个巨大的 XAML 中进行编译。我们获得的性能提升非常显着。在我的问题中,我写了“getMergedDictionaries 上的 1100 万次点击”......只是“预编译”了我们的一个程序集,我们下降到了 200 万次点击,并且整个应用程序的性能始终要好得多。
所以最后。 XAML 资源不应被视为经过编译的源代码,而应被理解为一种实际资源,在声明、存在时,会占用空间和性能。
好吧,我们必须以艰难的方式学习。我希望阅读本文的每个人都可以通过从我们的错误中吸取教训来改进他们的项目。

关于wpf - 合并字典和资源查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6693320/

相关文章:

wpf - 从另一个程序集为 WPF 中的 UserControl 设置样式

c# - 如何在不单击一次和任何其他第三方工具的情况下在 wpf 中添加软件更新程序?

python速度处理每行VS block

java - Android studio 注册无法使用

wpf - ResourceDictionary 源绑定(bind)到模块(用于本地化)

wpf - VS2017 : An Error Occured while finding the resource dictionary

c# - WPF 中的 MouseEnter 和 MouseLeave

c# - WPF:关闭和打开窗口

c# - 为什么 ScrollViewer 属性不影响标签?

C# - 对基元数组进行排序并跟踪其索引的最快方法