本文很长,没有耐心,想直接复制的就别看了。(因为确实没有东西可以复制,这里都是“渔”,没有鱼)
ListBox继承自ItemsControl,加入了一个selector对象,可以提供选择(单选、多选功能)。是和显示一个一个的对象。比如文件管理器。
ListView是Listbox上面加入了一个View对象,一般跟GirdView连用,适合显示一条一条的、每一条分好几个栏目的对象。比如百度云的下载管理器。
这里写的是ListBox。
在Blend软件(或者VisualStudio)中为Listbox创建模板副本:
可见,ListBox是一个border里面嵌套一个ScrollViewer。
在WPF当中,预先设定了两个可以滚动的元素。ScrollBar和ScrollViewer。ScrollView内嵌了横向和纵向的两个ScrollVar,还内嵌了一个Content Container,用来在可以滑动的区域显示其他的东西。所以说,ScrollView是一个封装ScrollBar功能的复合控件。一般不会单独使用ScrllViewer,但是非要这么用也行。单独使用ScrollViewer的时候,是直接可以看到滚动条的:
但是使用ListBox时,元素数量不够的时候就看不到滚动条:
为了能够自定义Listbox样式,先把Listbox改成ListViewer,同样用Blend(或者VisualStudio)创建副本,看到一下代码:
可见,一个ScrollViewer是一个grid被分成了四行四列:
Row=0、Col=0是内容区域;Row=0、Col=1是纵向的滚轮;Row=1、Col=0是横向滚轮,默认情况下是不可见的,能出现上面这个图是因为把上面代码中 PART_HorizontalScrollBar 的visibility手动设置成了visible,这样看起来直观一点;Row=1、Col=1这块区域被微软很形象的命名成了Corner。
OK,到这儿发现,想要自定义Listbox的样式,得先解决自定义ScrollBar,因为这个自带的Bar实在是太!丑!了!
OK,同样的套路,我们直接在windows里面随便建一个scrollbar:
嗯...很真实好吧,确实是一个奇丑无比的scrollbar。同样为其创建模板:
我靠!这么丑的玩意儿为什么要包含这么多代码!还真是Bar不可貌相。 =_=||
不要怕,慢慢看:
先找TargetType是ScrollBar的style:
有点长...只看布局,不开Triigers的话:
很明显,一个Bar被分成了三行。猜也猜的出来:上下两个button,中间一个滚动条。
先看Button,这里是Button的一种:RepeatButton,直接看他的Style:
去上面找这个Style:
也他妈好长...只看布局:
balabala
也就是说是一个Boder加上一个ContentPresenter,
再回到ScrollBar的Style:
这个Path就是ContentPresenter,也就是那个三角。试验一下,吧Path换成一个Image:
(要想成功运行还要改动触发器里面的内同,这里只是证明一下Path就是我们熟悉的那个三角)
下面那个RepeatButton是完全一样的。
最后就剩下这个Track了:
https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.primitives.track?view=netframework-4.7.2
上面是Track的官方文档:
很明显,Track自己又被方程了两个RepeatButton和Thumb。我们先看开你这两个RepeatButton:他们都是RepeatButtonTransparent样式。这里就不去仔细看这个样式了,最终的效果就是几乎透明的,我们可以随心所欲地再去更改了。
最后再看Thumb,它的Style是 :
其实就是一个Rectangle。
至此,所有的Listbox的样式全部解析完成(不包括触发器):
看起来很简单的ListBox其实是一个高度封装好的控件,但是其本质还是一些底层的控件,只要能内心的一步一步去解构,很快就能明白。明白了ListBox的样式之后,自定义一些样子的ListBox就变得简单了。