样式和模板的学习笔记

学到WPF的样式和模板章节,书中先讲的是样式,后讲的是模板,按照书中的例子都成功实现指定效果。然后学到样式和模板的混合使用,这里出了问题。

书中只给了模板的标签节点,和样式及样式引用模板的详细代码(是针对Button控件的)。我将这些代码引入窗口资源MainWindow.Resources中,然后在Grid中添加了一个Button,引用了其中一个样式(两个样式套用一个模板)。运行后窗口一片空白(因为我模板中没有代码),我想着应该是模板代码的问题,因为模板代码不全,那么我参照前面的模板章节,补充了模板代码。这时又出问题了,样式中的Background属性值不起作用了。我仔细想了一下,原来是因为自己图省事,直接在模板中做了一个Rectangle,并用Fill属性填充了指定的颜色。再回头看模板章节中,里面重点讲了模板绑定的限制有两条:1、仅在模板的可视化树内部;2、不能应用在Freezable派生对象的属性上,比如绑定Brush的Color属性会失败。对于第二条限制要使用常规的数据绑定来解决,于是我又在Gradient标签中添加如下属性:Color="{Binding RelativeSource={RelativeSource TemplateParent},Path=Background.Color}" 这个数据绑定有问题(注意加粗部分),结果我运行,系统报异常——无法从文本“TemplateParent”创建“RelativeSourceMode”。这个错误在之前学习模板时就犯过一次,不过这次又找了半天,才发现正确的应该是TemplatedParent,注意红色的d。这次再运行,就可以正常显示了,切换另一个样式,背景色就为另一个样式的颜色了。

这里总结如下几点:

1、样式可有x:Key也可没有,没有的时候必须指定TargetType,而有的时候必须在Button中指定x:Key值;另外如果没有TargetType时,里面的属性名称前面必须指明类型,如Button.Background。

2、模板如果不设置,系统会自动调用系统模板,系统的每一个控件都是一个完整外观的模板;这里说句题外的,用样式触发器设置按钮的IsMouseOver属性值(比如黄色),可是奇怪的是运行后,当鼠标放到按钮上,黄色一闪而过,接着仍然是系统自带的淡蓝色,这就是因为系统模板在作怪,要想去掉这个效果,我目前所知道的一个方式就是自己写个按钮模板(书上说样式优先级高于模板,自定义的样式和模板的优先级是这样,但是这个系统默认的模板效果却不能被自定义样式效果覆盖,不知道什么原因)。

3、模板如果设置了,就必须要在里面写代码,尤其是ViewBox中要写<ContentPresenter Margin="20" Content="{TemplateBinding Content}" />,否则你的控件会不呈现(注意:不是按钮不可见,而是根本就没有生成按钮,这与你把按钮设置成透明的不一样)。

4、注意数据绑定:你的按钮时圆形还是矩形,由你模板中的<Ellipse />和<Rectangle />来决定,你可以加入更复杂的图形,比如书中在将模板章节用到的例子就是用两个同心圆套在一起来表现,然后在图形中需要设置Fill属性,例子中用的是线性画刷LinearGradientBrush,并在画刷中使用GradientStop,画刷的使用我还太懂,不过其中的Color绑定是这样的,如果你将这里的Color设置成Red或者其他颜色,那么在样式中再设置背景色就没有任何用了,如果想在外部(如样式或具体某个按钮中)设置背景色,需要用这个绑定:{Binding RelativeSource={RelativeSource TemplatedParent},Path=Background.Color},一定要注意里面是TemplatedParent,否则会报错的。

5、最后,书上还说,模板是有弊端的,当你自定义模板后,该控件原有的系统属性统统消失,比如按钮禁用后变灰色,因此如果决定自定义控件模板,就需要对控件的所有行为负责,最终达到自己想要的效果。

最后啰嗦几句,这里学WPF所学用书是《葵花宝典——WPF自学手册》【李响】著{电子工业出版社},推荐大家阅读。另外这里并没有上代码,原因是这篇随笔不是教程,而是因学习不仔细所做的笔记。但是相信如果你把《葵花宝典。。。》一书的第十三章:样式和控件模板看完以后,大概可以猜到所涉及的代码,参考代码是“代码13-17 完善后的代码”、“代码13-20 修改后的程序”、“代码13-21 不修改模板,只是增加一个样式”。

posted @ 2013-04-23 10:36  守护晴天  阅读(452)  评论(0编辑  收藏  举报