访问控件库中定义的资源
Accessing resources defined in Controls Library
所以我在用户控件库中有几个 DataTemplate
。这些 DataTemplate
驻留在 themes\generic.xaml
资源字典中,可以毫无问题地在库项目中使用。
此库项目由主桌面应用程序项目使用,但在运行时 Application.Current.FindResource()
无法找到库中定义的任何资源。 (我以为会!)
所以我继续将该资源字典合并到应用程序资源字典中:
<Application x:Class="Application">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/ControlsLibraryProj;component/themes/generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
瞧!它现在可以访问那些 DataTemplate
。我的问题是,我做对了吗?我是否需要合并在引用项目中定义的字典?不知何故,我的印象是 Application.Current.FindResource()
可以访问所有已加载模块(exe 和 dll)中定义的所有资源。这是正确的吗?我是否通过合并不必要地加载了两次?
My question is, did I do it correctly?
是的。
Do I need to merge a dictionary defined in a referenced project?
是的,如果您打算在您的应用项目中实际使用引用项目中定义的样式。
唯一的例外是默认控件样式,即在引用项目中定义的任何控件的默认样式。这些是您通常在 themes/generic.xaml
中定义的控件,它们将应用于您在应用程序中创建的相应控件的任何实例,而无需合并 themes/generic.xaml
.
如果您自己编写了用户控件库,我宁愿建议您使用 generic.xaml
来为您的自定义控件声明资源。如果您不想或不能这样做,恕我直言,您应该使用 ComponentResourceKey.
您可以找到示例 here(查看 "Defining resources at the theme level" 部分)。
因此您的资源将声明为:
<LinearGradientBrush
x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:Painter}, ResourceId=ButtonBrush}"
StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Blue" Offset="0" />
<GradientStop Color="White" Offset=".8" />
</LinearGradientBrush>
而且你可以找回它
ComponentResourceKey brushKey = new ComponentResourceKey(typeof(Painter), "MyEllipseBrush");
ellipseBrush = (Brush)Application.Current.TryFindResource(brushKey);
请注意,因为:
Implicit style application does not occur on the theme level. Suppose
you want all the labels on your controls to have a certain style. If
you define the style in at the element level, you do not have to give
the style an explicit key, the labels will use the style
automatically. This is not the case for resources at the theme level.
You must define a key and reference the style every place you want to
use it.
希望对您有所帮助
所以我在用户控件库中有几个 DataTemplate
。这些 DataTemplate
驻留在 themes\generic.xaml
资源字典中,可以毫无问题地在库项目中使用。
此库项目由主桌面应用程序项目使用,但在运行时 Application.Current.FindResource()
无法找到库中定义的任何资源。 (我以为会!)
所以我继续将该资源字典合并到应用程序资源字典中:
<Application x:Class="Application">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/ControlsLibraryProj;component/themes/generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
瞧!它现在可以访问那些 DataTemplate
。我的问题是,我做对了吗?我是否需要合并在引用项目中定义的字典?不知何故,我的印象是 Application.Current.FindResource()
可以访问所有已加载模块(exe 和 dll)中定义的所有资源。这是正确的吗?我是否通过合并不必要地加载了两次?
My question is, did I do it correctly?
是的。
Do I need to merge a dictionary defined in a referenced project?
是的,如果您打算在您的应用项目中实际使用引用项目中定义的样式。
唯一的例外是默认控件样式,即在引用项目中定义的任何控件的默认样式。这些是您通常在 themes/generic.xaml
中定义的控件,它们将应用于您在应用程序中创建的相应控件的任何实例,而无需合并 themes/generic.xaml
.
如果您自己编写了用户控件库,我宁愿建议您使用 generic.xaml
来为您的自定义控件声明资源。如果您不想或不能这样做,恕我直言,您应该使用 ComponentResourceKey.
您可以找到示例 here(查看 "Defining resources at the theme level" 部分)。
因此您的资源将声明为:
<LinearGradientBrush
x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:Painter}, ResourceId=ButtonBrush}"
StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Blue" Offset="0" />
<GradientStop Color="White" Offset=".8" />
</LinearGradientBrush>
而且你可以找回它
ComponentResourceKey brushKey = new ComponentResourceKey(typeof(Painter), "MyEllipseBrush");
ellipseBrush = (Brush)Application.Current.TryFindResource(brushKey);
请注意,因为:
Implicit style application does not occur on the theme level. Suppose you want all the labels on your controls to have a certain style. If you define the style in at the element level, you do not have to give the style an explicit key, the labels will use the style automatically. This is not the case for resources at the theme level. You must define a key and reference the style every place you want to use it.
希望对您有所帮助