WPF中的Generic.xaml, theme以及custom control

原文:WPF中的Generic.xaml, theme以及custom control

在Visual Studio中创建自定义控件时,所有控件都将添加到/Themes/Generic.xaml

最近做的项目用了个漂亮的开源UI库,结果项目临近结尾发现要支持.Net 3.5, 然而那个UI库却最低支持4.0。欲哭无泪,最后决定拿掉那个库,自己改改style得了。深刻的教训。

作为程序员一般都比较害怕搞界面,这下硬着头皮上,折腾折腾Blend,抄抄改改各种style,弄着弄着居然能看懂个大概了。最后在自己建立的UI库项目中如何组织资源有了一些总结,进入正题:

“Generic.xaml” 早有耳闻,不清楚究竟有什么作用。这次Google之,*上早已有人发问。What is so special about Generic.xaml?

第一个答案清晰明了。

Every Control in WPF has a default Style that provides, among other things, the Control's default ControlTemplate. WPF looks for the default style in a special resource dictionary in the Themes folder in the same assembly as the control. The key for the default style is provided by the Control.DefaultStyleKey dependency property, the default value of which is overridden in each sub-class of Control.

The name of the resource dictionary depends on the current Windows theme e.g. on Vista using the Aero theme, the dictionary is called Aero.NormalColor.xaml, on XP using the default theme it is Luna.NormalColor.xaml. If the style is not found in the theme dictionary, it looks in Generic.xaml i.e for controls whose look doesn't depend on the theme.

This only applies to any custom controls you have defined i.e. classes derived from Control, directly or indirectly. You can change the default style for a standard control by deriving from it and calling DefaultStyleKeyProperty.OverrideMetadata in the static constructor, but you then have to supply the full style including ControlTemplate.

Note that you can tell WPF to look in an external assembly for your default style by using the ThemeInfo attribute. The external assembly must be named <YourAssembly>.<ThemeName>.dll e.g. PresententationFramework.Aero.dll.

讲解了Generic.xaml的来龙去脉。顺便提了如何使用DefaultStyleKeyProperty.OverrideMetadata 来改变WPF查找一个control的默认style时用的类型。还提到了 ThemeInfo.

下面这篇文章,Structuring Your XAML Sources,代码演示的非常清晰。通过它还能了解创建一个Custom Control的典型做法,很有帮助。总体来说,Generic.xaml在UI Library中的好处就是,使用这个library的项目不用再引用library的resource dictionary,UI Library中定义的custom control也能自动地找到它的默认style。

看文章附带的源代码,以及开源库的代码,发现它们都在AssemblyInfo.cs中有ThemeInfo. 这是必不可少的。

[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
上一篇:fireworks mx 2004 金属特效字制作方法


下一篇:MFC序列化与反序列化