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

Ara*_*and 3 wpf resources custom-controls

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

static SlimlineSimpleFieldTextBlock() {
         DefaultStyleKeyProperty.OverrideMetadata(typeof(SlimlineSimpleFieldTextBlock), new FrameworkPropertyMetadata(typeof(SlimlineSimpleFieldTextBlock)));
}
Run Code Online (Sandbox Code Playgroud)

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

Ray*_*rns 5

使用构造您的资源键ComponentResourceKey.仅在可视树和应用程序资源中搜索正常资源键.但是ComponentResourceKey,在包含该类型的程序集的主题词典中也搜索任何a的资源键.(对于Type用作资源键的对象也是如此.)

在包含名为"Sandwich"的控件的程序集的Themes/Generic.xaml中,您可能具有:

<SolidColorBrush x:Key="{ComponentResourceKey local:Sandwich, Lettuce}"
                 Color="#00FF00" />

<ControlTemplate x:Key="{ComponentResourceKey local:Sandwich, PeanutButter}" ...>
  ...
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)

您可以在以下代码中引用这些资源:

var lettuce = (Brush)FindResource(
                 new ComponentResourceKey(typeof(Sandwich), "Lettuce"));

var penutButter = (ControlTemplate)FindResource(
                 new ComponentResourceKey(typeof(Sandwich), "PeanutButter"));
Run Code Online (Sandbox Code Playgroud)

您也可以在XAML中引用这些资源,如下所示:

<Border Background="{StaticResource ResourceKey={ComponentResourceKey local:Sandwich, Lettuce}}" />
Run Code Online (Sandbox Code Playgroud)

这两种形式的引用都可以在任何可以使用FindResource的地方工作,它在代码内部或XAML中,用于从FrameworkElement,FrameworkContentElement或Application派生的任何对象.

补充说明

ComponentResourceKey资源的搜索算法仅涉及包含指定类型的程序集,而不涉及类型本身.因此,{ComponentResourceKey local:Sandwich,Seasonings}如果Soup和Sandwich类在同一个程序集中,则Soup 类型的控件可以使用ComponentResourceKey .只要ComponentResourceKey的所有内容完全匹配且资源实际上与给定类型在同一个程序集中,就会找到该资源.

另请注意,虽然可以使用pack URI从另一个程序集加载ResourceDictionary,但这样做是个坏主意.与Themes/Generic.xaml解决方案不同,您实际上必须使用控件修改应用程序,并且它还存在多重包含和可覆盖性问题.

无论何时使用Themes/Generic.xaml,都必须在该程序集上正确设置ThemeInfoAttribute.您可以从控件库的AssemblyInfo.cs开始:

[assembly:ThemeInfoAttribute(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
Run Code Online (Sandbox Code Playgroud)