今天说下wpf中的模板,前面一篇中我们讲到了style,但是style所能做的仅仅是在现有控件的基础上进行修修补补,但是如果我们想
彻底颠覆控件样式,那么我们就必须使用这一篇所说的模板。
老外写书都喜欢在篇头搞一个类图,方便我们宏观认识,这里我也上一个。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5yN2QDNwUjMycjM2AjMxAjMvwVM0cDNxIzLcJTMwIzLcNXZnFWbp9CXt92YuM3ZvxmYuNmLyADMjlGcvw1LcpDc0RHaiojIsJye.png)
一:控件模板
1:controltemplate
我们知道wpf的控件都是继承自control,在control类中有一个template属性,类型就是controltemplate。
那么利用这个controltemplate就可以彻底的颠覆控件的默认外观,这里我把一个checkbox变成一个小矩形,蛮有意思的。
确实,我们干了一件漂亮的事情,把checkbox变成了“小矩形”,但是我们发现了一个小问题,为什么我的content=“xxx”没有显示到模板上?
很简单,我们已经重定义了控件模板,默认模板将会被覆盖...
2:contentpresenter
幸好,wpf给我们提供了一个contentpresenter,它的作用就是把原有模板的属性原封不动的投放到自定义模板中。
当然你也可以玩一些小技巧,比如我想在"矩形“和”文字”中间设置边距,那么我们可以设置contentpresenter的margin。
如果你够聪明,你会发现我设置的margin是一个非常呆板的事情,意思就是说能不能根据具体控件灵活控制margin呢?答案肯定是没问题的,
因为我们记得一个控件可以绑定到另一个控件上,比如这里我将模板中的margin绑定到原控件中的padding上去。
3:trigger
我们知道style里面也是有trigger的,废话不多说,上代码说话。
最后形成的效果就是当checkbox选中时为实心框,不选中为空心框。
4:与style混搭
可能刚才我也说了,style只能在原有的控件基础上修修补补,如果我们让style修补control控件的template属性时,此时我们是不是
就可以实现controltemplate和style的混搭呢?
二:数据模板
现在我们已经知道“控件模板”是用于改变控件外观,那么“数据模板”顾名思义就是控制数据的显示方式,下面做个demo让person绑定到listbox上。
xaml:
最后我们发现,listbox中并没有呈现我们需要的数据,只是呈现了当前类的tostring()方法,很简单,因为我们绑定的不是简单的数据类型集合,
而是多字段的复杂类型,更重要的是我们并没有告诉wpf该如何呈现person数据。
<1>重写tostring()
既然wpf在render数据的时候呈现的是当前的tostring()形式,那下面我们来重写tostring()试试看。
最后看看效果,如我们所愿,person信息已经呈现。
<2>datatemplate重写
或许有的人比较苛刻,他需要person是作为矩形一块一块的呈现,而不是这些简单的形式,那么此时我们就可以用datatemplate来颠覆。
哈哈,果然是以一块一块的形式展现,大功告成,当然这里的”触发器“和”style混搭“跟conroltemplate非常相似,我想应该不需要累赘了。
三: itemspaneltemplate
在条目控件(itemcontrol)里面,有一个属性叫itempanel,类型是itempaneltemplate。
那么itemspaneltemplate主要用来干什么的呢?首先我们要知道常见的条目控件有:listbox,menu,statusbar,比如拿listbox来说,
我们经过仔细研究,发现itembox的itempanel其实是一个visualizingstackpanel,就是说listbox的每一项的排列方式是遵循stackpanel的
原则,也就是从上到下的排列方式,比如”一线码农“和”小师妹“是按照竖行排列方式,好,我现在的要求就是能够”横排“,该如何做到呢?
哈哈,确实有意思,我们改变了listbox中item的默认排序方向,当然在menu,statusbar中我们也可以用同样的方式来更改。
四: hierarchicaldatatemplate
它是针对具有分层数据结构的控件设计的,比如说treeview,相当于可以每一个层级上做datatemplate,很好很强大。