我有一个控件,我想在xaml文件中声明资源。如果这是一个用户控件,我可以将资源放在<UserControl.Resources>
块中,并通过this.Resources["myResourceKey"]
在代码中引用它们如何在控件中实现相同的功能。目前xaml的唯一链接是通过控件静态构造函数,引用样式(和控件模板)
static SlimlineSimpleFieldTextBlock() {
DefaultStyleKeyProperty.OverrideMetadata(typeof(SlimlineSimpleFieldTextBlock), new FrameworkPropertyMetadata(typeof(SlimlineSimpleFieldTextBlock)));
}
但即使我在xaml <Style.Resources>
中添加了一个块,我似乎也无法引用它们(因为在OnApplyTemplate阶段Style是null),即使我这样做也意味着如果某人eles覆盖了样式我会失去我的资源。
答案 0 :(得分:5)
使用ComponentResourceKey
构建资源键。仅在可视树和应用程序资源中搜索正常资源键。但是,在包含该类型的程序集的主题词典中也会搜索任何ComponentResourceKey
的资源键。 (对于用作资源键的Type
个对象也是如此。)
在包含名为“Sandwich”的控件的程序集的Themes / Generic.xaml中,您可能有:
<SolidColorBrush x:Key="{ComponentResourceKey local:Sandwich, Lettuce}"
Color="#00FF00" />
<ControlTemplate x:Key="{ComponentResourceKey local:Sandwich, PeanutButter}" ...>
...
</ControlTemplate>
您可以在以下代码中引用这些资源:
var lettuce = (Brush)FindResource(
new ComponentResourceKey(typeof(Sandwich), "Lettuce"));
var penutButter = (ControlTemplate)FindResource(
new ComponentResourceKey(typeof(Sandwich), "PeanutButter"));
你也可以像这样在XAML中引用这些资源:
<Border Background="{StaticResource ResourceKey={ComponentResourceKey local:Sandwich, Lettuce}}" />
这两种形式的引用都可以在任何可以使用FindResource的地方工作,它位于代码内部,XAML适用于派生自FrameworkElement,FrameworkContentElement或Application的任何对象。
附加说明
ComponentResourceKey资源的搜索算法仅涉及包含指定类型的程序集,而不涉及类型本身。因此,如果Soup和Sandwich类在同一个程序集中,则Soup类型的控件可以使用{ComponentResourceKey local:Sandwich,Seasonings}
的ComponentResourceKey。只要ComponentResourceKey的所有内容完全匹配,并且资源实际上与给定类型在同一个程序集中,就会找到该资源。
另请注意,虽然可以使用pack URI从另一个程序集加载ResourceDictionary,但这样做是个坏主意。与Themes / Generic.xaml解决方案不同,您实际上必须使用控件修改应用程序,并且还存在多重包含和可覆盖性问题。
每当使用Themes / Generic.xaml时,必须在该程序集上正确设置ThemeInfoAttribute。您可以从控件库的AssemblyInfo.cs开始:
[assembly:ThemeInfoAttribute(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]