繁体   English   中英

同一 ResourceDictionary 的多个实例

[英]Multiple instances of the same ResourceDictionary

我在网上找到了这篇关于提高ResourceDictionaries性能的文章,但问题是它已经很老了(2011)。 我正在考虑实现这样的东西,但我想知道微软是否没有在 .NET Framework 的最新版本中修复这个问题。 关于这个话题我有几个问题,我希望这里有人可以给出答案:

  1. .NET Framework 4.6.1 是否仍然通过创建多个实例来管理ResourceDictionaries ,每次将它们分配给控件时一个实例?
  2. 例如,当我的ResourceDictionary样式"CustomButtonStyle"在名为"StylesAssembly"程序"StylesAssembly"称为"ButtonStyles"时,它甚至是一个问题,然后在应用程序的App.xaml中引用该应用程序,该应用程序有 20 个带有CustomButtonStyle Buttons分配给它们?
  3. 我是否理解正确,在上述情况下,将有 20 个"ButtonStyles" ResourceDictionary实例?

感谢@mm8 发布您的答案。 这是 100% 正确的,我只想发布我自己的答案,因为我发现了一些有趣的东西,这对其他人可能有用。

答案是:如果在应用程序中引用 ResourceDictionary 实例将只创建一次(无论许多控件使用其样式),但每次在应用程序中也使用的另一个 ResourceDictionary 中引用它时,它将再次实例化。


所以为了给你这个案例的例子,假设我们有以下结构:

- StylesAssembly.dll
  - ButtonResourceDictionary.xaml
  - CustomButtonResourceDictionary.xaml

- Application.exe
  - App.xaml
  - MainWindow.xaml

ButtonResourceDictionary.xaml具有以下代码:

<Style x:Key="DefaultButtonStyle" TargetType="{x:Type Button}">
    <!-- Some setters -->
</Style>

CustomButtonResourceDictionary.xaml具有以下代码,它使用ButtonResourceDictionary.xaml

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="ButtonResourceDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>

<Style x:Key="CustomButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource DefaultButtonStyle}">
    <!-- Some setters -->
</Style>

Application.exe引用了StylesAssembly.dllApp.xaml 中有以下代码:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/StylesAssembly;component/ButtonResourceDictionary.xaml" />
            <ResourceDictionary Source="pack://application:,,,/StylesAssembly;component/CustomButtonResourceDictionary.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

现在,如果我们的MainWindow.xaml 中有这样的东西, ButtonResourceDictionary.xaml将只有一个实例

<StackPanel>
    <Button Style="{StaticResource DefaultButtonStyle}" />
    <Button Style="{StaticResource DefaultButtonStyle}" />
    <Button Style="{StaticResource DefaultButtonStyle}" />
    <Button Style="{StaticResource DefaultButtonStyle}" />
    <Button Style="{StaticResource DefaultButtonStyle}" />
</StackPanel>

但是如果我们的MainWindow.xaml 中有这样的东西, CustomButtonResourceDictionary.xaml将有一个实例,但ButtonResourceDictionary.xaml将有两个实例

<StackPanel>
    <Button Style="{StaticResource DefaultButtonStyle}" />
    <Button Style="{StaticResource DefaultButtonStyle}" />
    <Button Style="{StaticResource CustomButtonStyle}" />
    <Button Style="{StaticResource CustomButtonStyle}" />
    <Button Style="{StaticResource CustomButtonStyle}" />
</StackPanel>

这是因为前两个Buttons使用样式DefaultButtonStyleButtonResourceDictionary.xaml ,但另外三个Buttons使用样式CustomButtonStyle它来自CustomButtonResourceDictionary.xaml ,其中合并ButtonResourceDictionary.xaml在其代码。

我是否理解正确,在上述情况下,将有 20 个“ButtonStyles” ResourceDictionary实例?

不,只有一个。

当我的ResourceDictionary样式“CustomButtonStyle”在名为“StylesAssembly”的程序集中称为“ButtonStyles”时,它甚至是一个问题,然后在应用程序的App.xaml中引用它,该应用程序有 20 个带有 CustomButtonStyle 的按钮分配给它们?

如果您将ResourceDictionary合并到App.xaml并在应用程序的视图中创建 20 个Button元素,则仍然只会创建一个ResourceDictionary类的实例。

您可以通过向ResourceDictionary添加一个代码隐藏类来自己确认这一点:

是否可以在 WPF 中的资源字典后面设置代码以进行事件处理?

...并在构造函数中放置一个断点。

在创建的ResourceDictionary也将只有一个Style定义的实例。

我最近一直在与朋友一起研究替代解决方案,我想分享它。 目标是能够在任何地方使用 ResourceDictionaries 并以任何必要的方式合并它们,但仍然只实例化一次并且不会破坏 VS 设计器和 Blend 等。

指示:
1. 根据需要在 xaml 中使用合并的 ResourceDictionaries。
2.参考nuget包Sundew.Xaml.OptimizationsSundew.Xaml.Optimizer
3. 在你的项目根目录添加一个 sxo-settings.json 并启用 ResourceDictionaryCachingOptimizer
4. 构建
构建将使用缓存/共享 ResourceDictionary,但设计器也将工作,因为他们只能看到正常的 ResourceDictionary。

有关更多详细信息,请参阅: https : //github.com/hugener/Sundew.Xaml.Optimizations
和一个示例: https : //github.com/hugener/Sundew.Xaml.Optimizer.Sample

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM