Wpf 如何处理资源字典,使它们不';不要创建不必要的对象

Wpf 如何处理资源字典,使它们不';不要创建不必要的对象,wpf,xaml,resourcedictionary,Wpf,Xaml,Resourcedictionary,例如,我将一些常用的资源移到了ResourceDictionary中 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Style x:Key="SaveButtonStyle" TargetType="{x:Type Button}">

例如,我将一些常用的资源移到了ResourceDictionary中

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Style x:Key="SaveButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="IsDefault" Value="True" />
    <Setter Property="IsCancel" Value="False" />
    <Setter Property="ToolTip" Value="Close and save any changes you have made." />
  </Style>
  <Style x:Key="CloseButtonStyle" BasedOn="{StaticResource XSaveCloseButtonStyle}" TargetType="{x:Type Button}">
    <Setter Property="IsDefault" Value="False" />
    <Setter Property="IsCancel" Value="True" />
    <Setter Property="ToolTip" Value="Close window." />
  </Style>
 </ResourceDictionary>

原因很简单,我需要在多个地方使用相同的样式。但是我发现了一个问题,如果在某个地方我只需要使用CloseButtonStyle,并且我引用了这个资源字典。我认为它创建了这两种样式,我做了一个小测试,并通过方法FindResource查看了后面的代码,看看是否会得到每种样式的一个实例,我做到了。
所以我的问题是我该如何处理这个问题?如果我只需要一个对象,我不想创建两个对象,但我也不想通过在许多地方复制和粘贴来编写这种样式

您可以执行以下操作:

  • 将样式存储在工作目录或资源中的文件中(一个文件对应一个样式)
  • 创建类(例如ResourcesHolder),该类将通过其键向您提供资源(就像FindResource一样)
  • ResourcesHolder具有FindResource(字符串resourceName)方法,该方法:
    • 在与resourceName同名的资源中搜索文件
    • 使用XamlReader解析它并返回
  • ResourcesHolder类包含存储解析对象的字典。到,如果已解析任何资源,您将从此词典返回:

    private Dictionary<string, object> storedObjects;
    
    public object FindResource(string resourceName)
    {
        if (storedObjects.ContainsKey(resourceName))
            return storedObjects[resourceName];
    
        else
            //search, parse and return new resource
    }
    
    在控件/窗口中:

        public partial class TestWindow : Window
        {
            public TestWindow()
            {
                ResourceHolder.Load("SaveButtonStyle");
                ResourceHolder.Load("CloseButtonStyle");
                InitializeComponent();
            }
        }
    
    在本例中,您可以在xaml中使用{StaticResource}扩展名


    如果您想在xaml中像{StaticResource}或{DynamicResource}那样自动执行,您必须编写自己的markupextension,调用ResourceHolder本身的Load或FindResource方法

    Make 2 Dictionary?@Kilazur我想过,这对于小项目来说是可以的,但是如果我有几百种不同控件的样式,故事板、数据模板等。我当然不想有这么多的资源字典。呃,我不知道。例如,MahApps为每个重新设置样式的控件使用一个字典,为每个主题颜色使用一个字典,为浅主题或暗主题使用另外两个字典。即使在UI设计中,分离关注点也是一件事;)你为什么要把它们分开?如果您希望获得卓越的性能,那么肯定不会以WPF:pHi VMaleev结束,谢谢您的回答,因此,如果我理解正确,这将有两个作用(甚至比我想象的还要多:)。首先,它不会创建我不需要的样式,其次,如果已经创建了一个样式,而其他东西需要它,它只会重用它,而不是重新创建它。我做对了吗?听起来不错:)如果我想从许多不同的视图访问它,我想ResourceHolder需要是静态的。我不明白的是,当视图创建时,我如何截取它以查看资源是否已创建,如果我发现它已创建,我如何阻止视图重新创建它并使用已经存在的内容。谢谢:)请检查我的编辑,如果我没有回答您的问题,请随时再问一遍=)非常感谢:)我开始将资源词典分解为具有单一样式的文件。然后我尝试了其他更合理的方法:)
        public partial class TestWindow : Window
        {
            public TestWindow()
            {
                ResourceHolder.Load("SaveButtonStyle");
                ResourceHolder.Load("CloseButtonStyle");
                InitializeComponent();
            }
        }