同一ResourceDictionary

时间:2017-10-18 11:01:13

标签: c# wpf xaml resourcedictionary

我发现this post关于改善网络上ResourceDictionaries的效果,但问题是它已经很久了(2011)。我正在考虑实现这样的东西,但我想知道微软是否在.NET Framework的最新版本中没有修复它。关于这个话题我几乎没有问题,我希望这里有人能给出答案:

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

3 个答案:

答案 0 :(得分:2)

  

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

没有。只有一个。

  

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

如果您将ResourceDictionary合并到App.xaml并在应用中的视图中创建了20个Button元素,那么ResourceDictionary类只会有一个实例创建

您可以通过向ResourceDictionary

添加代码隐藏类来自行确认

Is it possible to set code behind a resource dictionary in WPF for event handling?

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

创建的Style中只会定义ResourceDictionary的一个实例。

答案 1 :(得分:1)

感谢@ 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.dll App.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使用了DefaultButtonStyle中的ButtonResourceDictionary.xaml样式,而另外三个Buttons使用来自CustomButtonStyle的{​​{1}}样式CustomButtonResourceDictionary.xaml ,在其代码中合并ButtonResourceDictionary.xaml

答案 2 :(得分:0)

我最近一直在和一个朋友一起研究一种替代解决方案,我想分享它。目标是能够在任何地方使用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