欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

WPF滑块控件(Slider)的自定义样式

程序员文章站 2022-04-29 14:26:53
前言 每次开发滑块控件的样式都要花很久去读样式代码,感觉有点记不牢,所以特此备忘。 自定义滑块样式 首先创建项目,添加Slider控件。 然后获取Slider的Window样式,如下图操作。 然后弹出界面如下.我们点击确定。 点击确定后,我们的页面的Resources中,增加了一系列样式代码,而滑块 ......

前言

每次开发滑块控件的样式都要花很久去读样式代码,感觉有点记不牢,所以特此备忘。

自定义滑块样式

首先创建项目,添加slider控件。

然后获取slider的window样式,如下图操作。

WPF滑块控件(Slider)的自定义样式

然后弹出界面如下.我们点击确定。

WPF滑块控件(Slider)的自定义样式

点击确定后,我们的页面的resources中,增加了一系列样式代码,而滑块代码会被修改为如下样子:

<slider horizontalalignment="left"  width="200" verticalalignment="top" style="{dynamicresource sliderstyle1}"/>

可以看到,系统为我们的slider控件增加了样式——style="{dynamicresource sliderstyle1}"

现在我们查看样式sliderstyle1,f12跟踪到定义。

<style x:key="sliderstyle1" targettype="{x:type slider}">
    <setter property="stylus.ispressandholdenabled" value="false"/>
    <setter property="background" value="transparent"/>
    <setter property="borderbrush" value="transparent"/>
    <setter property="foreground" value="{staticresource sliderthumb.static.foreground}"/>
    <setter property="template" value="{staticresource sliderhorizontal}"/>
    <style.triggers>
        <trigger property="orientation" value="vertical">
            <setter property="template" value="{staticresource slidervertical}"/>
        </trigger>
    </style.triggers>
</style>

上述代码中我们可以看发现slider使用的模板是sliderhorizontal,但当他的排列方向为vertical时,则使用slidervertical模板。

因为slider控件默认是横向布局,所以我们先修改sliderhorizontal模板,对slider进行下美化。

同样,我们继续f12跟进sliderhorizontal的定义。

 <controltemplate x:key="sliderhorizontal" targettype="{x:type slider}">
            <border x:name="border" borderbrush="{templatebinding borderbrush}" borderthickness="{templatebinding borderthickness}" background="{templatebinding background}" snapstodevicepixels="true">
                <grid>
                    <grid.rowdefinitions>
                        <rowdefinition height="auto"/>
                        <rowdefinition height="auto" minheight="{templatebinding minheight}"/>
                        <rowdefinition height="auto"/>
                    </grid.rowdefinitions>
                    <tickbar x:name="toptick" fill="{templatebinding foreground}" height="4" margin="0,0,0,2" placement="top" grid.row="0" visibility="collapsed"/>
                    <tickbar x:name="bottomtick" fill="{templatebinding foreground}" height="4" margin="0,2,0,0" placement="bottom" grid.row="2" visibility="collapsed"/>
                    <border x:name="trackbackground" borderbrush="{staticresource sliderthumb.track.border}" borderthickness="1" background="{staticresource sliderthumb.track.background}" height="4.0" margin="5,0" grid.row="1" verticalalignment="center">
                        <canvas margin="-6,-1">
                            <rectangle x:name="part_selectionrange" fill="{dynamicresource {x:static systemcolors.highlightbrushkey}}" height="4.0" visibility="hidden"/>
                        </canvas>
                    </border>
                    <track x:name="part_track" grid.row="1">
                        <track.decreaserepeatbutton>
                            <repeatbutton command="{x:static slider.decreaselarge}" style="{staticresource repeatbuttontransparent}"/>
                        </track.decreaserepeatbutton>
                        <track.increaserepeatbutton>
                            <repeatbutton command="{x:static slider.increaselarge}" style="{staticresource repeatbuttontransparent}"/>
                        </track.increaserepeatbutton>
                        <track.thumb>
                            <thumb x:name="thumb" focusable="false" height="18" overridesdefaultstyle="true" template="{staticresource sliderthumbhorizontaldefault}" verticalalignment="center" width="11"/>
                        </track.thumb>
                    </track>
                </grid>
            </border>
            <controltemplate.triggers>
                <trigger property="tickplacement" value="topleft">
                    <setter property="visibility" targetname="toptick" value="visible"/>
                    <setter property="template" targetname="thumb" value="{staticresource sliderthumbhorizontaltop}"/>
                    <setter property="margin" targetname="trackbackground" value="5,2,5,0"/>
                </trigger>
                <trigger property="tickplacement" value="bottomright">
                    <setter property="visibility" targetname="bottomtick" value="visible"/>
                    <setter property="template" targetname="thumb" value="{staticresource sliderthumbhorizontalbottom}"/>
                    <setter property="margin" targetname="trackbackground" value="5,0,5,2"/>
                </trigger>
                <trigger property="tickplacement" value="both">
                    <setter property="visibility" targetname="toptick" value="visible"/>
                    <setter property="visibility" targetname="bottomtick" value="visible"/>
                </trigger>
                <trigger property="isselectionrangeenabled" value="true">
                    <setter property="visibility" targetname="part_selectionrange" value="visible"/>
                </trigger>
                <trigger property="iskeyboardfocused" value="true">
                    <setter property="foreground" targetname="thumb" value="blue"/>
                </trigger>
            </controltemplate.triggers>
        </controltemplate>

sliderhorizontal模板的定义比较多,这里直接定义到重点内容——轨道。

首先定位到代码【border x:name="trackbackground"】,这里的trackbackground是控制滑块背景颜色的,我们修改其背景颜色和边框颜色。

 <border x:name="trackbackground" borderbrush="red" borderthickness="1" background="yellow" height="4.0" margin="5,0" grid.row="1" verticalalignment="center">
     <canvas margin="-6,-1">
         <rectangle x:name="part_selectionrange" fill="{dynamicresource {x:static systemcolors.highlightbrushkey}}" height="4.0" visibility="hidden"/>
     </canvas>
 </border>

得到效果如下:

WPF滑块控件(Slider)的自定义样式

但我们有时候需要拖动前后颜色不一样,此时就靠背景修改就不够了。

在sliderhorizontal模板中找到decreaserepeatbutton和increaserepeatbutton;这两个一个是拖动前覆盖颜色,一个是拖动后覆盖颜色。

修改代码如下:

<track x:name="part_track" grid.row="1">
    <track.decreaserepeatbutton>
        <repeatbutton height="4" background="gray" command="{x:static slider.decreaselarge}" style="{staticresource repeatbuttontransparent}"/>
    </track.decreaserepeatbutton>
    <track.increaserepeatbutton>
        <repeatbutton height="4" background="green" command="{x:static slider.increaselarge}" style="{staticresource repeatbuttontransparent}"/>
    </track.increaserepeatbutton>
    <track.thumb>
        <thumb x:name="thumb" focusable="false" height="18" overridesdefaultstyle="true" template="{staticresource sliderthumbhorizontaldefault}" verticalalignment="center" width="11"/>
    </track.thumb>
</track>

得到效果如下:

WPF滑块控件(Slider)的自定义样式

注意这里的height一定要给值。

现在,我们设置好了轨道,可当前的滑块的颜色我们有点不太满意,所以我们再来处理下滑块。

滑块模板的模板是上方代码中粉色标记的代码——thumb。

可以看到thumb使用的是sliderthumbhorizontaldefault模板,所以,我们继续f12跟进sliderthumbhorizontaldefault查看它的定义。

<controltemplate x:key="sliderthumbhorizontaldefault" targettype="{x:type thumb}">
    <grid horizontalalignment="center" uselayoutrounding="true" verticalalignment="center">
        <path x:name="grip" data="m 0,0 c0,0 11,0 11,0 11,0 11,18 11,18 11,18 0,18 0,18 0,18 0,0 0,0 z" fill="{staticresource sliderthumb.static.background}" stretch="fill" snapstodevicepixels="true" stroke="{staticresource sliderthumb.static.border}" strokethickness="1" uselayoutrounding="true" verticalalignment="center"/>
    </grid>
    <controltemplate.triggers>
        <trigger property="ismouseover" value="true">
            <setter property="fill" targetname="grip" value="{staticresource sliderthumb.mouseover.background}"/>
            <setter property="stroke" targetname="grip" value="{staticresource sliderthumb.mouseover.border}"/>
        </trigger>
        <trigger property="isdragging" value="true">
            <setter property="fill" targetname="grip" value="{staticresource sliderthumb.pressed.background}"/>
            <setter property="stroke" targetname="grip" value="{staticresource sliderthumb.pressed.border}"/>
        </trigger>
        <trigger property="isenabled" value="false">
            <setter property="fill" targetname="grip" value="{staticresource sliderthumb.disabled.background}"/>
            <setter property="stroke" targetname="grip" value="{staticresource sliderthumb.disabled.border}"/>
        </trigger>
    </controltemplate.triggers>
</controltemplate>

从上述代码中可以看到,滑块定义很简单,布局就是一个grid里放了一个path,事件响应只有3个。

下面为修改path的fill填充色和stroke的划线颜色如下:

 <path x:name="grip" data="m 0,0 c0,0 11,0 11,0 11,0 11,18 11,18 11,18 0,18 0,18 0,18 0,0 0,0 z" fill="red" stretch="fill" snapstodevicepixels="true" stroke="blue" strokethickness="1" uselayoutrounding="true" verticalalignment="center"/>

得到效果如下:

WPF滑块控件(Slider)的自定义样式

现在,我们觉得矩形的滑块不好看,需要用椭圆形的滑块,那么,我们再来处理下滑块。

首先删除thumb里定义的宽和高,因为不删除它们,模板里的宽高会受此限制。

删除后如下:

 <track.thumb>
     <thumb x:name="thumb" focusable="false"   overridesdefaultstyle="true" template="{staticresource sliderthumbhorizontaldefault}" verticalalignment="center" />
 </track.thumb>

现在我们再来修改sliderthumbhorizontaldefault模板。

在模板里找到path,修改他的data,之前他的data是自己画的一个矩形,现在我们给他改为椭圆形,并且给path重新设置宽高,如下:

<path x:name="grip" width="20" height="20" fill="red" stretch="fill" snapstodevicepixels="true" stroke="blue" strokethickness="1" uselayoutrounding="true" verticalalignment="center">
    <path.data>
        <ellipsegeometry center="10,10" radiusx="10" radiusy="10"></ellipsegeometry>
    </path.data>
</path>

我们得到效果如下:

WPF滑块控件(Slider)的自定义样式

可以看到,图中的滑块是个圆形,而我们需要的是一个椭圆形。

处理很简单,修改path的width即可,我们该为14,得到效果如下:

WPF滑块控件(Slider)的自定义样式

当然,我们既然可以通过修改样式设计椭圆形滑块,就也可以设计其他形状滑块,比如,我们修改path如下,获得斜角四边形滑块:

<path x:name="grip" width="14" height="20" fill="red" stretch="fill" snapstodevicepixels="true" stroke="blue" strokethickness="1" uselayoutrounding="true" verticalalignment="center">
    <path.data>
        <pathgeometry>
            <pathgeometry.figures>
                <pathfigure startpoint="0,0" isclosed="true">
                    <linesegment point="0,0" />
                    <linesegment point="110,0" />
                    <linesegment point="70,40" />
                    <linesegment point="-40,40" />
                </pathfigure>
            </pathgeometry.figures>
        </pathgeometry>
    </path.data>
</path> 

效果图如下:

WPF滑块控件(Slider)的自定义样式

修改代码如下,设置三角形滑块:

<path x:name="grip" width="14" height="20" fill="red" stretch="fill" snapstodevicepixels="true" stroke="blue" strokethickness="1" uselayoutrounding="true" verticalalignment="center">
    <path.data>
        <pathgeometry>
            <pathgeometry.figures>
                <pathfigure startpoint="0,0" isclosed="true">
                    <linesegment point="30,0" />
                    <linesegment point="15,100" />
                </pathfigure>
            </pathgeometry.figures>
        </pathgeometry>
    </path.data>
</path> 

效果图如下:

WPF滑块控件(Slider)的自定义样式

----------------------------------------------------------------------------------------------------

上述代码设置的都是水平方向的滑块样式,垂直方向的滑块样式设置同理,只要从模板slidervertical开始,以此处理修改即可。

----------------------------------------------------------------------------------------------------

到此wpf滑块控件(slider)的自定义样式就已经讲解完成了。

代码已经传到github上了,欢迎大家下载。

github地址:https://github.com/kiba518/wpfslider

----------------------------------------------------------------------------------------------------

注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!
若您觉得这篇文章还不错,请点击下方的推荐】,非常感谢!