当前位置: 移动技术网 > IT编程>开发语言>.net > WPF滑块控件(Slider)的自定义样式

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

2019年08月01日  | 移动技术网IT编程  | 我要评论

男模鸟,马鞍山四村小学,2013年安徽国剧盛典

前言

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

自定义滑块样式

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

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

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

点击确定后,我们的页面的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>

得到效果如下:

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

在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>

得到效果如下:

注意这里的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"/>

得到效果如下:

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

首先删除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>

我们得到效果如下:

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

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

当然,我们既然可以通过修改样式设计椭圆形滑块,就也可以设计其他形状滑块,比如,我们修改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> 

效果图如下:

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

<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> 

效果图如下:

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

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

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

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

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

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

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

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

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网