WPF:访问控件程序集中的资源

时间:2010-06-23 06:28:08

标签: wpf resources custom-controls

我有一个控件,我想在xaml文件中声明资源。如果这是一个用户控件,我可以将资源放在<UserControl.Resources>块中,并通过this.Resources["myResourceKey"]在代码中引用它们如何在控件中实现相同的功能。目前xaml的唯一链接是通过控件静态构造函数,引用样式(和控件模板)

static SlimlineSimpleFieldTextBlock() {
         DefaultStyleKeyProperty.OverrideMetadata(typeof(SlimlineSimpleFieldTextBlock), new FrameworkPropertyMetadata(typeof(SlimlineSimpleFieldTextBlock)));
}

但即使我在xaml <Style.Resources>中添加了一个块,我似乎也无法引用它们(因为在OnApplyTemplate阶段Style是null),即使我这样做也意味着如果某人eles覆盖了样式我会失去我的资源。

1 个答案:

答案 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)]