Generic.xaml有什么特别之处?

173

我一直在尝试找出如何组织我的ResourceDictionary文件以便与团队其他成员进行重用和共享。

我不断地遇到"Generic.xaml",但如果我在MSDN上寻找Generic.xaml或只是在Google上搜索,我只能找到提到它的博客文章和论坛问题--似乎我无法找到任何真正权威和清晰的东西。

Generic.xaml和MyRandomlyNamedResourceDictionary.xaml之间有什么区别?看起来无论哪种方式,我都必须使用Source属性引用存储在库中的ResourceDictionaries。例如:

<Application.Resources>
    <ResourceDictionary
        Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml"
</Application.Resources>

那么,Generic.xaml 到底有什么优势呢?如果我不想给我的应用程序提供多个“外观”(即,如果我只有一个主题),它是否有任何用处?


6
如果你使用自定义控件(而不是用户控件),则不需要将generic.xaml字典合并到你的代码中。 - Eternal21
2个回答

171

WPF中的每个控件都有一个默认样式,其中包括控件的默认ControlTemplate。 WPF在与控件相同的程序集的Themes文件夹中查找默认样式的特殊资源字典。默认样式的键由Control.DefaultStyleKey依赖属性提供,其默认值在每个Control子类中被覆盖。

资源字典的名称取决于当前的Windows主题,例如,在使用Aero主题的Vista上,字典称为Aero.NormalColor.xaml,在使用默认主题的XP上,它是Luna.NormalColor.xaml。如果在主题字典中找不到样式,则在Generic.xaml中查找,即对于外观不取决于主题的控件。

这仅适用于您定义的任何自定义控件,即直接或间接从Control派生的类。您可以通过从其派生并在静态构造函数中调用DefaultStyleKeyProperty.OverrideMetadata来更改标准控件的默认样式,但您需要提供完整的样式,包括ControlTemplate。

请注意,您可以使用ThemeInfo属性告诉WPF查找您的默认样式所在的外部程序集。外部程序集必须命名为<YourAssembly>.<ThemeName>.dll,例如PresentationFramework.Aero.dll。


谢谢,Phil。那么你的意思是,如果我只想为普通按钮控件提供一个新的ControlTemplate(即不编写从Button派生的自定义类),这不会被视为“主题”的一部分? - devuxer
是的,如果您只想重新模板化或重新设计标准控件,则可以在UserControl/Window/Application/Whatever级别使用普通的Resources元素。您可以使用具有隐式键的样式(http://msdn.microsoft.com/en-us/library/ms750613.aspx#stylesimplicitkeys)来更改某种类型的所有控件。 - Phil Devaney
@Zaheylu 现在可以工作了(我想微软正在更新他们的文档) - Alan McBee

114
对于一个名为generic.xaml的文件(不区分大小写),要使其成为特殊文件,必须满足两个条件:
  • 它必须位于项目中的“Themes”子根文件夹中。
  • 程序集必须标记有ThemeInfoAttribute(通常在AssemblyInfo.cs中)。
然后,它将作为任何默认样式的查找位置,您可以将其应用于您的控件。同时请注意,样式必须声明其TargetType和x:Key均为要样式化的控件类型,才能成为默认样式。
如果您希望向应用程序添加整个主题和主题切换,并需要编写代码实现此功能,那么该技术仅定义了默认资源字典。

3
你能否澄清一下你所说的“默认样式”是什么意思?这是否意味着所有按钮都会自动采用TargetType为“Button”的样式,还是我仍然需要通过编写<Button Style="{StaticResource MyButtonStyle}" />来引用x:Key?如果ResourceDictionary中包含多个TargetType为“Button”的样式,会发生什么情况?谢谢。 - devuxer
3
帮助我更好地理解,还有一个问题:Generic.xaml是WPF中与CSS文件相当的东西,用于定义不同元素的默认外观,例如 h1 {color:#00ff00} 吗? - devuxer
3
是的,如果没有明确引用键,那么默认样式将应用;如果有两个相同的样式,会出现“字典中有两个相同的键”的错误。是的,你可以这样考虑默认行为。 - Kenan E. K.
3
虽然generic.xaml文件本身存在特殊限制,但是generic.xaml内的字典条目可以是一个合并字典,其条目可以引用任何内容。 - Tormod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接