最新消息:最新信息可以到系统基本设置里填写,如果不想要这一栏可以修改head.htm,将第53行到55行删除即可

WPF如何自定义TabControl控件样式示例详解

创意新鲜 dedesos.com

一、前言

程序中经常会用到tabcontrol控件,默认的控件样式很普通。而且样式或功能不一定符合我们的要求。比如:我们需要tabcontrol的标题能够居中、或平均分布;或者我们希望tabcontrol的标题能够进行关闭。要实现这些功能我们需要对tabcontrol的样式进行定义。

二、实现tabcontrol的标题平均分布

默认的tabcontrol标题是使用tabpanel容器包含的。要想实现tabcontrol标题头平均分布,需要把tabpanel替换成uniformgrid;

替换后的tabcontrol样式如下:

 style x:key="tabcontrolstyle" targettype="{x:type tabcontrol}" 
 setter property="padding" 线上百家乐value="2"/ 
 setter property="horizontalcontentalignment" value="center"/ 
 setter property="verticalcontentalignment" value="center"/ 
 setter property="background" value="white"/ 
 setter property="borderbrush" value="#ffacacac"/ 
 setter property="borderthickness" value="1"/ 
 setter property="foreground" value="{dynamicresource {x:static systemcolors.controltextbrushkey}}"/ 
 setter property="template" 
 setter.value 
 controltemplate targettype="{x:type tabcontrol}" 
 grid x:name="templateroot" cliptobounds="true" snapstodevicepixels="true" keyboardnavigation.tabnavigation="local" 
 grid.columndefinitions 
 columndefinition x:name="columndefinition0"/ 
 columndefinition x:name="columndefinition1" width="0"/ 
 /grid.columndefinitions 
 grid.rowdefinitions 
 rowdefinition x:name="rowdefinition0" height="auto"/ 
 rowdefinition x:name="rowdefinition1" height="*"/ 
 /grid.rowdefinitions 
 uniformgrid x:name="headerpanel" rows="1" background="transparent" grid.column="0" isitemshost="true" margin="0" grid.row="0" keyboardnavigation.tabindex="1" panel.zindex="1"/ 
 line x1="0" x2="{binding actualwidth, relativesource={relativesource self}}" stroke="white" strokethickness="0.1" verticalalignment="bottom" margin="0 0 0 1" snapstodevicepixels="true"/ 
 border x:name="contentpanel" borderbrush="{templatebinding borderbrush}" borderthickness="{templatebinding borderthickness}" background="{templatebinding background}" grid.column="0" keyboardnavigation.directionalnavigation="contained" grid.row="1" keyboardnavigation.tabindex="2" keyboardnavigation.tabnavigation="local" 
 contentpresenter x:name="part_selectedcontenthost" contenttemplate="{templatebinding selectedcontenttemplate}" content="{templatebinding selectedcontent}" contentstringformat="{templatebinding selectedcontentstringformat}" contentsource="selectedcontent" margin="0" snapstodevicepixels="{templatebinding snapstodevicepixels}"/ 
 /border 
 /grid 
 controltemplate.triggers 
 trigger property="tabstripplacement" value="bottom" 
 setter property="grid.row" targetname="headerpanel" value="1"/ 
 setter property="grid.row" targetname="contentpanel" value="0"/ 
 setter property="height" targetname="rowdefinition0" value="*"/ 
 setter property="height" targetname="rowdefinition1" value="auto"/ 
 /trigger 
 trigger property="tabstripplacement" value="left" 
 setter property="grid.row" targetname="headerpanel" value="0"/ 
 setter property="grid.row" targetname="contentpanel" value="0"/ 
 setter property="grid.column" targetname="headerpanel" value="0"/ 
 setter property="grid.column" targetname="contentpanel" value="1"/ 
 setter property="width" targetname="columndefinition0" value="auto"/ 
 setter property="width" targetname="columndefinition1" value="*"/ 
 setter property="height" targetname="rowdefinition0" value="*"/ 
 setter property="height" targetname="rowdefinition1" value="0"/ 
 /trigger 
 trigger property="tabstripplacement" value="right" 
 setter property="grid.row" targetname="headerpanel" value="0"/ 
 setter property="grid.row" targetname="contentpanel" value="0"/ 
 setter property="grid.column" targetname="headerpanel" value="1"/ 
 setter property="grid.column" targetname="contentpanel" value="0"/ 
 setter property="width" targetname="columndefinition0" value="*"/ 
 setter property="width" targetname="columndefinition1" value="auto"/ 
 setter property="height" targetname="rowdefinition0" value="*"/ 
 setter property="height" targetname="rowdefinition1" value="0"/ 
 /trigger 
 trigger property="isenabled" value="false" 
 setter property="textelement.foreground" targetname="templateroot" value="{dynamicresource {x:static systemcolors.graytextbrushkey}}"/ 
 /trigger 
 /controltemplate.triggers 
 /controltemplate 
 /setter.value 
 /setter 
 /style 

即使这样设置了,tabcontrol的标题还是很丑,这个时候就需要通过设置tabitem来更改标题样式了。

tabitem样式如下:

 style x:key="tabitemstyle" targettype="{x:type tabitem}" 
 setter property="foreground" value="white"/ 
 setter property="background" value="transparent"/ 
 setter property="borderbrush" value="#ffacacac"/ 
 setter property="margin" value="0"/ 
 setter property="horizontalcontentalignment" value="stretch"/ 
 setter property="verticalcontentalignment" value="stretch"/ 
 setter property="template" 
 setter.value 
 controltemplate targettype="{x:type tabitem}" 
 grid x:name="templateroot" snapstodevicepixels="true" background="transparent" 
 textblock x:name="txt" visibility="visible" verticalalignment="center" horizontalalignment="center" text="{templatebinding header}" tooltip="{templatebinding header}" foreground="{templatebinding foreground}" texttrimming="characterellipsis" / 
 /grid 
 controltemplate.triggers 
 multidatatrigger 
 multidatatrigger.conditions 
 condition binding="{binding ismouseover, relativesource={relativesource self}}" value="true"/ 
 condition binding="{binding tabstripplacement, relativesource={relativesource findancestor, ancestorlevel=1, ancestortype={x:type tabcontrol}}}" value="top"/ 
 /multidatatrigger.conditions 
 setter property="foreground" targetname="txt" value="#fffea1"/ 
 /multidatatrigger 
 multidatatrigger 
 multidatatrigger.conditions 
 condition binding="{binding isenabled, relativesource={relativesource self}}" value="false"/ 
 condition binding="{binding tabstripplacement, relativesource={relativesource findancestor, ancestorlevel=1, ancestortype={x:type tabcontrol}}}" value="left"/ 
 /multidatatrigger.conditions 
 setter property="opacity" targetname="templateroot" value="0.56"/ 
 /multidatatrigger 
 multidatatrigger 
 multidatatrigger.conditions 
 condition binding="{binding isenabled, relativesource={relativesource self}}" value="false"/ 
 condition binding="{binding tabstripplacement, relativesource={relativesource findancestor, ancestorlevel=1, ancestortype={x:type tabcontrol}}}" value="bottom"/ 
 /multidatatrigger.conditions 
 setter property="opacity" targetname="templateroot" value="0.56"/ 
 /multidatatrigger 
 multidatatrigger 
 multidatatrigger.conditions 
 condition binding="{binding isenabled, relativesource={relativesource self}}" value="false"/ 
 condition binding="{binding tabstripplacement, relativesource={relativesource findancestor, ancestorlevel=1, ancestortype={x:type tabcontrol}}}" value="right"/ 
 /multidatatrigger.conditions 
 setter property="opacity" targetname="templateroot" value="0.56"/ 
 /multidatatrigger 
 multidatatrigger 
 multidatatrigger.conditions 
 condition binding="{binding isenabled, relativesource={relativesource self}}" value="false"/ 
 condition binding="{binding tabstripplacement, relativesource={relativesource findancestor, ancestorlevel=1, ancestortype={x:type tabcontrol}}}" value="top"/ 
 /multidatatrigger.conditions 
 setter property="opacity" targetname="templateroot" value="0.56"/ 
 /multidatatrigger 
 multidatatrigger 
 multidatatrigger.conditions 
 condition binding="{binding isselected, relativesource={relativesource self}}" value="true"/ 
 condition binding="{binding tabstripplacement, relativesource={relativesource findancestor, ancestorlevel=1, ancestortype={x:type tabcontrol}}}" value="top"/ 
 /multidatatrigger.conditions 
 setter property="panel.zindex" value="1"/ 
 setter property="foreground" targetname="txt" value="#fffea1"/ 
 /multidatatrigger 
 /controltemplate.triggers 
 /controltemplate 
 /setter.value 
 /setter 
 /style 

至此,样式已经设置完毕,引用示例:

 grid background="#858586" 
 tabcontrol width="300" height="200" background="transparent" borderbrush="transparent" borderthickness="0" 
 tabitem cursor="hand" header="音乐电台" height="38" 
 grid background="#33ffffff" 
 textblock text="音乐电台" verticalalignment="center" horizontalalignment="center"/ 
 /grid 
 /tabitem 
 tabitem cursor="hand" header="mv电台" height="38" 
 grid background="#33ffffff" 
 textblock text="mv电台" verticalalignment="center" horizontalalignment="center"/ 
 /grid 
 /tabitem 
 /tabcontrol 
 /grid 

效果如下:

三、实现tabcontrol标题居中显示

同理需要更改tabcontrol的样式和tabitem的样式。需要把使用tabpanel作为标题的容器,设置horizontalalignment为center;

tabcontrol的样式如下:

 style x:key="tabcontrolwithunderlinestyle" targettype="{x:type tabcontrol}" 
 setter property="padding" value="2"/ 
 setter property="horizontalcontentalignment" value="center"/ 
 setter property="verticalcontentalignment" value="center"/ 
 setter property="background" value="white"/ 
 setter property="borderbrush" value="#ffacacac"/ 
 setter property="borderthickness" value="1"/ 
 setter property="foreground" value="{dynamicresource {x:static systemcolors.controltextbrushkey}}"/ 
 setter property="template" 
 setter.value 
 controltemplate targettype="{x:type tabcontrol}" 
 grid x:name="templateroot" cliptobounds="true" snapstodevicepixels="true" keyboardnavigation.tabnavigation="local" 
 grid.columndefinitions 
 columndefinition x:name="columndefinition0"/ 
 columndefinition x:name="columndefinition1" width="0"/ 
 /grid.columndefinitions 
 grid.rowdefinitions 
 rowdefinition x:name="rowdefinition0" height="auto"/ 
 rowdefinition x:name="rowdefinition1" height="*"/ 
 /grid.rowdefinitions 
 tabpanel x:name="headerpanel" horizontalalignment="center" background="transparent" grid.column="0" isitemshost="true" margin="0" grid.row="0" keyboardnavigation.tabindex="1" panel.zindex="1"/ 
 line x1="0" x2="{binding actualwidth, relativesource={relativesource self}}" stroke="gray" strokethickness="0.1" verticalalignment="bottom" margin="0 0 0 1" snapstodevicepixels="true"/ 
 border x:name="contentpanel" borderbrush="{templatebinding borderbrush}" borderthickness="{templatebinding borderthickness}" background="{templatebinding background}" grid.column="0" keyboardnavigation.directionalnavigation="contained" grid.row="1" keyboardnavigation.tabindex="2" keyboardnavigation.tabnavigation="local" 
 contentpresenter x:name="part_selectedcontenthost" contenttemplate="{templatebinding selectedcontenttemplate}" content="{templatebinding selectedcontent}" contentstringformat="{templatebinding selectedcontentstringformat}" contentsource="selectedcontent" margin="0" snapstodevicepixels="{templatebinding snapstodevicepixels}"/ 
 /border 
 /grid 
 controltemplate.triggers 
 trigger property="tabstripplacement" value="bottom" 
 setter property="grid.row" targetname="headerpanel" value="1"/ 
 setter property="grid.row" targetname="contentpanel" value="0"/ 
 setter property="height" targetname="rowdefinition0" value="*"/ 
 setter property="height" targetname="rowdefinition1" value="auto"/ 
 /trigger 
 trigger property="tabstripplacement" value="left" 
 setter property="grid.row" targetname="headerpanel" value="0"/ 
 setter property="grid.row" targetname="contentpanel" value="0"/ 
 setter property="grid.column" targetname="headerpanel" value="0"/ 
 setter property="grid.column" targetname="contentpanel" value="1"/ 
 setter property="width" targetname="columndefinition0" value="auto"/ 
 setter property="width" targetname="columndefinition1" value="*"/ 
 setter property="height" targetname="rowdefinition0" value="*"/ 
 setter property="height" targetname="rowdefinition1" value="0"/ 
 /trigger 
 trigger property="tabstripplacement" value="right" 
 setter property="grid.row" targetname="headerpanel" value="0"/ 
 setter property="grid.row" targetname="contentpanel" value="0"/ 
 setter property="grid.column" targetname="headerpanel" value="1"/ 
 setter property="grid.column" targetname="contentpanel" value="0"/ 
 setter property="width" targetname="columndefinition0" value="*"/ 
 setter property="width" targetname="columndefinition1" value="auto"/ 
 setter property="height" targetname="rowdefinition0" value="*"/ 
 setter property="height" targetname="rowdefinition1" value="0"/ 
 /trigger 
 trigger property="isenabled" value="false" 
 setter property="textelement.foreground" targetname="templateroot" value="{dynamicresource {x:static systemcolors.graytextbrushkey}}"/ 
 /trigger 
 /controltemplate.triggers 
 /controltemplate 
 /setter.value 
 /setter 
 /style 

tabitem样式如下:

 style x:key="tabitemexwithunderlinestyle" targettype="{x:type tabitem}" 
 setter property="foreground" value="white"/ 
 setter property="background" value="transparent"/ 
 setter property="borderbrush" value="#ffacacac"/ 
 setter property="margin" value="0"/ 
 setter property="horizontalcontentalignment" value="stretch"/ 
 setter property="verticalcontentalignment" value="stretch"/ 
 setter property="template" 
 setter.value 
 controltemplate targettype="{x:type tabitem}" 
 grid x:name="templateroot" snapstodevicepixels="true" background="transparent" 
 border x:name="_underline" borderbrush="#37aefe" borderthickness="0" margin="{templatebinding margin}"/ 
 grid 
 textblock x:name="txt" visibility="visible" verticalalignment="center" horizontalalignment="center" text="{templatebinding header}" tooltip="{templatebinding header}" foreground="{templatebinding foreground}" texttrimming="characterellipsis" / 
 /grid 
 /grid 
 controltemplate.triggers 
 multidatatrigger 
 multidatatrigger.conditions 
 condition binding="{binding ismouseover, relativesource={relativesource self}}" value="true"/ 
 condition binding="{binding tabstripplacement, relativesource={relativesource findancestor, ancestorlevel=1, ancestortype={x:type tabcontrol}}}" value="top"/ 
 /multidatatrigger.conditions 
 setter property="foreground" targetname="txt" value="#37aefe"/ 
 /multidatatrigger 
 multidatatrigger 
 multidatatrigger.conditions 
 condition binding="{binding isenabled, relativesource={relativesource self}}" value="false"/ 
 condition binding="{binding tabstripplacement, relativesource={relativesource findancestor, ancestorlevel=1, ancestortype={x:type tabcontrol}}}" value="left"/ 
 /multidatatrigger.conditions 
 setter property="opacity" targetname="templateroot" value="0.56"/ 
 /multidatatrigger 
 multidatatrigger 
 multidatatrigger.conditions 
 condition binding="{binding isenabled, relativesource={relativesource self}}" value="false"/ 
 condition binding="{binding tabstripplacement, relativesource={relativesource findancestor, ancestorlevel=1, ancestortype={x:type tabcontrol}}}" value="bottom"/ 
 /multidatatrigger.conditions 
 setter property="opacity" targetname="templateroot" value="0.56"/ 
 /multidatatrigger 
 multidatatrigger 
 multidatatrigger.conditions 
 condition binding="{binding isenabled, relativesource={relativesource self}}" value="false"/ 
 condition binding="{binding tabstripplacement, relativesource={relativesource findancestor, ancestorlevel=1, ancestortype={x:type tabcontrol}}}" value="right"/ 
 /multidatatrigger.conditions 
 setter property="opacity" targetname="templateroot" value="0.56"/ 
 /multidatatrigger 
 multidatatrigger 
 multidatatrigger.conditions 
 condition binding="{binding isenabled, relativesource={relativesource self}}" value="false"/ 
 condition binding="{binding tabstripplacement, relativesource={relativesource findancestor, ancestorlevel=1, ancestortype={x:type tabcontrol}}}" value="top"/ 
 /multidatatrigger.conditions 
 setter property="opacity" targetname="templateroot" value="0.56"/ 
 /multidatatrigger 
 multidatatrigger 
 multidatatrigger.conditions 
 condition binding="{binding isselected, relativesource={relativesource self}}" value="true"/ 
 condition binding="{binding tabstripplacement, relativesource={relativesource findancestor, ancestorlevel=1, ancestortype={x:type tabcontrol}}}" value="top"/ /multidatatrigger.conditions 
 setter property="panel.zindex" value="1"/ 
 setter property="foreground" targetname="txt" value="#37aefe"/ 
 setter property="borderthickness" targetname="_underline" value="0 0 0 2"/ 
 /multidatatrigger 
 /controltemplate.triggers 
 /controltemplate 
 /setter.value 
 /setter 
 /style 

引用示例:

 grid background="#858586" 
 tabcontrol foreground="black" width="300" height="200" background="transparent" borderbrush="transparent" borderthickness="0" 
 tabitem cursor="hand" header="音乐电台" height="38" width="70" margin="5 0" 
 grid background="#33ffffff" 
 textblock text="音乐电台" verticalalignment="center" horizontalalignment="center"/ 
 /grid 
 /tabitem 
 tabitem cursor="hand" header="mv电台" height="38" width="70" margin="5 0" 
 grid background="#33ffffff" 
 textblock text="mv电台" verticalalignment="center" horizontalalignment="center"/ 
 /grid 
 /tabitem 
 /tabcontrol 
 /grid 

效果如下:

四、带关闭按钮的tabcontrol

带关闭按钮的tabcontrol其实就是就是扩展tabitem,需要新建wpf自定义控件,命名为tabitemclose吧;

c#代码如下:

public class tabitemclose : tabitem
 static tabitemclose
 defaultstylekeyproperty.overridemetadata, new frameworkpropertymetadata));
 private static void onpropertychanged
 d.setvalue;
 /// summary 
 /// 是否可以关闭
 /// /summary 
 public bool iscanclose
 get { return getvalue; }
 set { setvalue; }
 public static readonly dependencyproperty iscancloseproperty =
 dependencyproperty.register, typeof, new propertymetadata);
 /// summary 
 /// 关闭的图标
 /// /summary 
 public imagesource closeicon
 get { return getvalue; }
 set { setvalue; }
 public static readonly dependencyproperty closeiconproperty =
 dependencyproperty.register, typeof, new propertymetadata);

    与本文相关的文章

    网友最新评论