如何从C#代码访问wpf中的ResourceDictionary?

如何从C#代码访问wpf中的ResourceDictionary?,c#,wpf,resources,C#,Wpf,Resources,我在xaml文件中定义了一个DataTemplate,我希望通过C#code访问该文件。 有人能告诉我如何访问它吗? 我添加了一个新的ResourceDictionary文件,其名称为Dictionary1.xaml。 我有一个数据模板,例如: <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.

我在xaml文件中定义了一个
DataTemplate
,我希望通过C#code访问该文件。 有人能告诉我如何访问它吗? 我添加了一个新的
ResourceDictionary
文件,其名称为Dictionary1.xaml。 我有一个数据模板,例如:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DataTemplate x:Key="mytemplate">
        <TextBlock Text="Name:" Background="Blue"/>
    </DataTemplate>
</ResourceDictionary>

不是,我有一个名为listBox1的
ListBox
,我想将它分配给它的
Itemtemplate
属性
但是我不明白我该怎么做?

例如,如果您在App.xaml文件的资源字典中有一个按钮模板,您可以使用以下代码访问它:

Application.Current.Resources[typeof(Button)]

你到底在哪里定义它

如果在对象的ResourceDictionary中定义它,则

Application.Current.Resources[typeof(yourDataTemplateTargetType)] 
应该有用。如果将其定义为其他对象(例如ItemsControl)的成员,则需要获取ItemsControl实例的句柄并调用ItemTemplate属性

编辑:好的,我想我们有进展了。因此,您正在自己的文件中定义ResourceDictionary。在UI中使用它并从代码隐藏中访问它之前,需要将该ResourceDictionary合并到应用程序中。你在这么做吗

如果是,那么下一步就是获取此资源。每个FrameworkElement都有一个名为的方法。这种方法很好,因为它沿着ResourceDictionary树走,并尝试用键定位资源。因此,如果要从UserControl访问此资源,可以在代码隐藏中执行以下操作:

FindResource(typeof(yourDataTemplateTargetType));

如果这对您不起作用,请向我们确切说明您是如何声明此资源字典的,以及它是如何合并到您的应用程序资源中的。

因为
应用程序。在我的情况下,当前的
为空,我最终使用了以下内容:

    var myResourceDictionary = new ResourceDictionary();
    myResourceDictionary.Source =
        new Uri("/DllName;component/Resources/MyResourceDictionary.xaml",
                UriKind.RelativeOrAbsolute);  
然后使用
myResourceDictionary[“KeyName”]作为项目类型


()

您可以访问添加到项目中的资源字典,如下所示:

var rd = new ResourceDictionary();
rd.Source = new Uri("ms-appx:///Dictionary1.xaml");
public static MyDictionary ConstructInitializedInstance()
{
    var dictionary = new MyDictionary();
    dictionary.InitializeComponent();
    return dictionary;
}
然后,您可以访问存储在资源字典中的资源,如下所示:

someObject.Property = rd["mytemplate"];
注意:

您必须根据创建的URI相对于项目基本目录的位置修改资源字典的URI。

以上任何方法都可以根据位置获取资源,如果您遵循MVVMm,我建议您这样做:

  • 创建一个类似ProvideDataTemplateService的服务(创建一个从行为继承的服务)
  • 使用您选择的容器将此服务注入到您希望对DataTemple拥有ACE的位置
    我在这里找到了答案

    • 创建ressource字典“ColorResources.xaml”
    • 加上: 蓝色的

    • 编辑app.xml并添加:

    • 使用代码中的颜色

      var color=(System.Windows.Media.color)Application.Current.FindResource(“ButtonColor1”)


    管理员:你能修改代码吗?它不会显示,谢谢

    如果您在同一个项目中获得资源,请尝试以下操作:

    yourControl.Style = FindResource("YourResourceKey") as Style;
    
    ResourceDictionary res = (ResourceDictionary)Application.LoadComponent(new Uri("/ProjectName;component/FolderName/ResourceDictionaryName.xaml", UriKind.Relative)); 
    yourControl.Style = (Style)res["YourResourceKey"];
    
    否则,请尝试以下操作:

    yourControl.Style = FindResource("YourResourceKey") as Style;
    
    ResourceDictionary res = (ResourceDictionary)Application.LoadComponent(new Uri("/ProjectName;component/FolderName/ResourceDictionaryName.xaml", UriKind.Relative)); 
    yourControl.Style = (Style)res["YourResourceKey"];
    

    如果您使用下面的代码合并了资源字典

    <Window x:Class="MainWindow">
        <Window.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="DefaultStyle.xaml"/>
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Window.Resources>
    </Window>
    
    var style = Application.Current.MainWindow.Resources["ResourceKey"];
    // OR
    var style = Application.Current.MainWindow.TryFindResource("ResourceKey");
    

    就我的一生而言,虽然我能够通过XAML加载我的资源字典,但我无法通过“代码隐藏”(C#)加载它

    所以我求助于让视图加载它:(MyView.xaml)

    
    
    然后在我的UT中通过实例化该视图并访问它来访问它:

    new MyView().Resources.MergedDictionaries[0]


    Hacky,但有效。

    只是为了在这里添加另一个答案,以防您没有视图或
    应用程序。当前的
    为空。我意识到这可能不常见,但在我的例子中,父应用程序和
    应用程序都有一个addin;我还想将我的一个资源作为
    ImageSource
    传递给父级,因此我不需要创建XAML视图来直接从中获取资源

    您还可以将字典变成代码隐藏的可创建对象。只需在XAML中设置
    x:Class
    属性,然后在代码隐藏中创建一个
    .XAML.cs
    文件。更新后的XAML(让我们调用代码文件
    MyDictionary.XAML
    )将如下所示:

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                        x:Class="Some.Namespace.MyDictionary"
                        mc:Ignorable="d">
        ...Resources...
    </ResourceDictionary>
    
    using System.Windows;
    
    namespace Some.Namespace
    {
        public partial class MyDictionary : ResourceDictionary
        {
            public MyDictionary()
            {
                InitializeComponent();
            }
        }
    }
    
    var dictionary = new MyDictionary();
    var resource = dictionary["whateverKey"] as WhateverResourceType;
    
    不要忘记调用
    InitializeComponent()
    ,因为这是加载资源的原因实际上并不抱歉,请参见下面的编辑

    完成此操作后,您只需在代码中的任意位置构造类的实例,并按键引用资源,如下所示:

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                        x:Class="Some.Namespace.MyDictionary"
                        mc:Ignorable="d">
        ...Resources...
    </ResourceDictionary>
    
    using System.Windows;
    
    namespace Some.Namespace
    {
        public partial class MyDictionary : ResourceDictionary
        {
            public MyDictionary()
            {
                InitializeComponent();
            }
        }
    }
    
    var dictionary = new MyDictionary();
    var resource = dictionary["whateverKey"] as WhateverResourceType;
    
    感谢你提出这个想法

    编辑

    只是遇到了一个潜在的问题。我的一些控件上出现了“无法重新初始化ResourceDictionary实例”异常。在进一步研究中,这可能与在构造函数中调用
    InitializeComponent
    有关。相反,我从代码背后删除了构造函数,并添加了一个静态方法来获取初始化实例,如下所示:

    var rd = new ResourceDictionary();
    rd.Source = new Uri("ms-appx:///Dictionary1.xaml");
    
    public static MyDictionary ConstructInitializedInstance()
    {
        var dictionary = new MyDictionary();
        dictionary.InitializeComponent();
        return dictionary;
    }
    

    您也可以在代码中创建和初始化。

    我不明白。此答案不使用键。FindResource接受一个参数,即键。typeof(yourDataTemplateTargetType)是本例中的键。Hi。如果键不是类型,而是OP示例中的字符串,该怎么办?是否应该在DataTemplate元素上设置DataType属性,而不是使用字符串键?它可以是任何东西。FindResource的参数类型是object。我个人认为这是最好的方法,就好像你要在库或任何地方定义它一样,它仍然可以工作,作为公认的答案,你必须将所有字典合并到你的应用程序中,这可能有点过分,或者不可行。
    “component/Styles/Icons.xaml”
    如果字典不在di中也足够了