WPF类库中的程序集范围/根级别样式

我有一个支持WPF(基于本文 )的C#(2008 / .NET 3.5)类库程序集。
我创build了几个窗口,现在正在尝试为它们创build一个通用样式集。 但是,由于它是一个类库(而不是WPF应用程序),我没有一个app.xaml(及其包含的应用程序和相应的Application.Resources)来存储这些样式以进行全局访问。

所以: 如果我没有app.xaml(见上文),我怎样才能创build一个顶级的样式定义集合,这些样式定义将被程序集中的所有xaml文件看到 ? 和/或是否可以添加一个工作的app.xaml到类库?

仅供参考,我曾尝试在ResourceDictionary.xaml文件中创buildResourceDictionary,并将其包含在“Window.Resources”块中的每个窗口中。 原来,解决了button等的风格,但不是封闭的窗口。 我可以把Style="{StaticResource MyWindowStyle}"放在窗口的开始块中,它会在VSdevise窗口中编译和显示,但是在实际的运行过程中,我得到一个parsingexception(MyWindowStyle找不到;我正在猜测Visual Studio看到包含在该行后面的字典,但CRL更顺序地执行,因此尚未加载ResourceDictionary)。


感谢您的想法,但仍然没有去…显然,类库不隐式地支持generic.xaml用法。 我将generic.xaml添加到我的类库项目,并将其构build操作设置为“资源”。 它包含:

 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Style TargetType="{x:Type Window}" x:Key="MyWindow"> <Setter Property="Background" Value="Black"/> </Style> </ResourceDictionary> 

我想要使​​用主题的窗口xaml如下所示:

 <Window x:Class="MyAssembly.ConfigureGenericButtons" x:ClassModifier="internal" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Style="{StaticResource MyWindow}" Title="ConfigureGenericButtons"> ...Buttons, etc... </Window> 

虽然VSdevise窗口没有使用MyWindow风格(即黑色背景)显示窗口,但编译良好并启动。 但是,当包含此类库的应用程序调用导致此窗口显示时,我得到一个XamlParseException:

找不到名为“{MyWindow}”的资源。

我也试过忽略了Style参数,看看窗口是否会默认使用这个样式(我试过用generic.xaml中的x:Key来包含和不包含)。 没有错误,但在generic.xaml中定义的任何东西都没有显示出来。

我在这里做错了什么,或者有什么其他想法可以允许在窗口上使用常用的自定义样式(即,不必在每个窗口的xaml中定义样式) – 但是这不是一个应用?

尝试添加

 Style={DynamicResource MyStyle} 

在这种情况下你不能使用StaticResource。

这听起来像是一个主题工作。

  1. /themes/generic.xaml ResourceDictionary添加到您的项目中。
  2. 将以下内容添加到AssemblyInfo.cs中: [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
  3. 利润!

您添加到通用的任何资源都将被所有控件使用。 您还可以通过在themes目录中包含具有正确主题名称的ResourceDictionary文件来制作特定于configuration文件的主题(Luna,Aero等)。

下面是更多信息的链接: 创build并应用自定义主题

如果你没有一个app.xaml,你仍然可以将它加载到appplication级别的资源中,但是你必须编写代码(而不是xaml)来完成它,类似于这个…

 void LoadIt() { ResourceDictionary MyResourceDictionary = new ResourceDictionary(); MyResourceDictionary.Source = new Uri("MyResources.xaml", UriKind.Relative); App.Current.Resources.MergedDictionaries.Add( MyResourceDictionary ) } 

看看这个网站的例子: http : //ascendedguard.com/2007/08/one-of-nice-features-about-wpf-is-how.html

WPF博士(或以前称为WPF博士的人)在这个问题上有很好的职位 。

以下是他们创buildApplication对象并添加资源的文章摘录:

 if (Application.Current == null) { // create the Application object new Application(); // merge in your application resources Application.Current.Resources.MergedDictionaries.Add( Application.LoadComponent( new Uri("MyLibrary;component/Resources/MyResourceDictionary.xaml", UriKind.Relative)) as ResourceDictionary); } 

由于我的程序集通过互操作托pipe,我不得不添加设置ShutdownMode如下,完成时关机:

 new Application() { ShutdownMode = ShutdownMode.OnExplicitShutdown }; 

它像一个魅力工作。

如果将其加载到Window.Resource中,字典仅适用于该窗口的子项。 你需要把它提供给窗口和它的孩子。

尝试加载它在你的app.xaml文件。 这应该使其成为应用程序级资源,而不是窗口级资源。

所以花了很多时间后,我终于明白了这一点。 就是这样:

  1. 在WPF控件库中,添加一个名为themes的新文件夹。
  2. themes文件夹内,添加一个名为generic.xaml的资源字典。
  3. generic.xaml ,使用以下语法添加您的资源:

     <SolidColorBrush x:Key="{ComponentResourceKey {x:Type local:UserControl1}, MyEllipseBrush}" Color="Blue" /> 
  4. 在您的控制中,使用以下语法来访问此资源:

     Background="{StaticResource {ComponentResourceKey {x:Type local:UserControl1}, MyEllipseBrush}}" 

注意事项:

  1. 当您创build新的WPF控件库时,步骤1和2通常由Visual Studio自动完成。
  2. 我不完全理解ComponentResourceKey的第一个参数的用途,但它是必需的。 使用将使用此资源的控件的名称。
  3. Visual Studio的devise者无法find我的案例中的资源。 这可能是caching问题,我不确定。 但在运行时,它运行整齐。
  4. 您可以在此MSDN文章中阅读有关此语法的更多详细信息。

希望这可以让一些生活更轻松。