如何从C#代码访问wpf中的ResourceDictionary?
我在xaml文件中定义了一个如何从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.
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中也足够了