WPF-控件模板
说起控件模板,还是因为在一次需求实现中,我碰到了一个圆形按钮。一开始我认知的按钮是方形灰不拉几的一个块儿。这如何实现一个圆形按钮?
我最先想到的是使用样式,可是发现根本就没有改变Button形状的属性。
于是翻阅了一下《WPF编程宝典》,看到控件模板那章觉得说的好牛逼哦,但是我还是觉得一头雾水。然后又翻了翻《深入浅出WPF》里面的深入浅出话模板,刘铁猛老师还是稳啊。
什么是控件模板,我的理解就是:控件模板给控件整容,比如垫个鼻子、埋个线等等;反正整的你都不认识它原来长什么样子了。
什么?你说控件模板是给控件整容?那我还学过给控件设置背景色,前景色等等属性呀,难道它不能完成整容么?
哈哈,我认为给控件设置属性只能起到化妆的效果,比如妹子虽然化妆了变好看了,但是还远远达不到给控件整容这么粗暴的效果呀。
通过上面的话是想告诉大家,控件模板的威力。我们正是开始看一看如何通过控件模板实现一个圆形Button吧。
第一步:既然要整容,就要知道我还是挺想知道整容前Button长啥样,我随便建立了一个WPF项目,添加了一个Button进去,运行起来。通过可视化树我找到了这个Button的组成:

第二步:开始整容,查阅资料得知所有的控件都有Templete属性,就是为了让我们整容用的,代码如下:
<Button Content="哈哈" VerticalAlignment="Center" HorizontalAlignment="Center">
<!--Templete属性的值就是我们所说的ControlTemplete即控件模板-->
<Button.Template>
<ControlTemplate TargetType="Button">
<!--写你想写的吧-->
</ControlTemplate>
</Button.Template>
</Button>
添加进去ControlTemplete后,直接编辑器预览界面就啥都看不见了,证明这个人貌似被我毁容了~~~ 不慌我们继续。
第三步:在ControTemplete标签中,写我们想写的代码吧,知道了原生Button的样子,我们就利用Grid作为父容器,Ellipse作为背景,来给Button整个容吧。
<Button Content="哈哈" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White">
<!--Templete属性的值就是我们所说的ControlTemplete即控件模板-->
<Button.Template>
<ControlTemplate TargetType="Button">
<!--我们就只添加一个Ellipse好了 麻雀虽小 但是你不能说他就不是Button了-->
<Grid>
<Ellipse Width="50" Height="50" Fill="Blue"/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>

实现是实现了,可是我发现我点不了了,这和一个普通的Ellipse做成的圆有什么区别???怕是在逗我?
所以这里也要提醒大家,整容就要给人家整到位,写控件模板,只把布局写了只能算是完成了一半,我们还需要添加控件模板的Trigger属性,Trigger可是一个控件的灵魂之一哦。
第四步:给你的控件添加Trigger。Trigger里面的好多属性编译器没有智能提示 ~~~ emmm 需要自己敲!!!!没错你要自己敲!!!(略坑,吐槽一下微软~~~~)。
<Button Content="哈哈" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White">
<!--Templete属性的值就是我们所说的ControlTemplete即控件模板-->
<Button.Template>
<!--这里TargetType是一定要写的哦 不写的话很多属性编译器认不出来-->
<!--TarGetType有另外一种写法 TargetType={x:Type Button}-->
<ControlTemplate TargetType="Button">
<!--我们就只添加一个Ellipse好了 麻雀虽小 但是你不能说他不是Button了-->
<Grid>
<Ellipse x:Name="ball" Width="50" Height="50" Fill="Blue"/>
</Grid>
<!--添加鼠标移入移出的效果,让别人知道它是一个鲜活的Button-->
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" TargetName="ball" Value="LightBlue"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Fill" TargetName="ball" Value="DarkBlue"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
好啦,添加完trigger后,就真的像一个圆形按钮了,哈哈。来个GIF看下效果吧。

别急,结束了么?注意按钮的文本不见了!!!《WPF编程宝典》中告诉我们,所有控件都需要有一个ContenPresenter元素--它表示"在此插入内容",缺少它是不可以的。我们在上面直接给丢了。
第五步:在控件模板中添加ContentPresenter元素,让控件的内容显示出来。
<Button Content="哈哈" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White">
<!--Templete属性的值就是我们所说的ControlTemplete即控件模板-->
<Button.Template>
<!--这里TargetType是一定要写的哦 不写的话很多属性编译器认不出来-->
<!--TarGetType有另外一种写法 TargetType={x:Type Button}-->
<ControlTemplate TargetType="Button">
<!--Grid作为父容器 用于承载布局元素-->
<Grid>
<!--Ellipse在这里充当背景 代替原生的button里面的border元素-->
<Ellipse x:Name="ball" Width="50" Height="50" Fill="Blue"/>
<!--ContentPresenter在原生button就有,我们一定要带上它,可别丢掉-->
<ContentPresenter VerticalAlignment="{TemplateBinding VerticalAlignment}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"/>
</Grid>
<!--添加鼠标移入移出的效果,让别人知道它是一个鲜活的Button-->
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" TargetName="ball" Value="LightBlue"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Fill" TargetName="ball" Value="DarkBlue"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
最后一个要注意的是 TempleteBinding--模板绑定,WPF创造出来这个东西,是让我们的模板能够从应用模板中提取一个值供我们的模板使用。这个也要用上哦~~~。
好了,终于完成了一个圆形按钮,GIF效果图结束本次分享:

WPF-控件模板的更多相关文章
- c#字符串加载wpf控件模板代码 - 简书
原文:c#字符串加载wpf控件模板代码 - 简书 ResourceManager resManagerA = new ResourceManager("cn.qssq666.Properti ...
- WPF控件模板
引言:在进行WPF项目开发过程中,由于项目的需要,经常要对某个控件进行特殊的设定,其中就牵涉到模板的相关方面的内容.本文也是在自己进行项目开发过程中遇到控件模板设定时集中搜集资料后整理出来的,以供在以 ...
- WPF控件模板(6)
什么是ControlTemplate? ControlTemplate(控件模板)不仅是用于来定义控件的外观.样式, 还可通过控件模板的触发器(ControlTemplate.Triggers)修改控 ...
- 转载 WPF -- 控件模板 (ControlTemplate)(一) https://blog.csdn.net/qq_23018459/article/details/79899838
ControlTemplate(控件模板) https://blog.csdn.net/qq_23018459/article/details/79899838 WPF包含数据模板和控件模板,其中 ...
- WPF控件模板和数据模板
来自:http://www.th7.cn/Program/WPF/2011/12/21/51676.shtml ControlTemplate用于描述控件本身. 使用TemplateBinding来绑 ...
- WPF控件模板和数据模板 - 醉意人间
来自:http://www.th7.cn/Program/WPF/2011/12/21/51676.shtml ControlTemplate用于描述控件本身. 使用TemplateBinding来绑 ...
- WPF中的ControlTemplate(控件模板)(转)
原文地址 http://www.cnblogs.com/zhouyinhui/archive/2007/03/28/690993.html WPF中的ControlTemplate(控件模板) ...
- 《Programming WPF》翻译 第5章 7.控件模板
原文:<Programming WPF>翻译 第5章 7.控件模板 如果仔细的看我们当前的TTT游戏,会发现Button对象并没有完全为我们工作.哪些TTT面板有内圆角? 图5-14 这里 ...
- WPF笔记(1.9 样式和控件模板)——Hello,WPF!
原文:WPF笔记(1.9 样式和控件模板)--Hello,WPF! 资源的另一个用途是样式设置: <Window > <Window.Resources> <St ...
- WPF基础篇之控件模板(ControlTemplate)
WPF中每一个控件都有一个默认的模板,该模板描述了控件的外观以及外观对外界刺激所做出的反应.我们可以自定义一个模板来替换掉控件的默认模板以便打造个性化的控件. 与Style不同,Style只能改变控件 ...
随机推荐
- C#比较两个对象中的指定字段值是否相等
一.创建CompareFieldAttribute标识要比较的字段 using System; namespace CompareObjField { /// <summary> /// ...
- Mac下安装adb
1.检查是否安装adb briandeMacBook-Pro:~ brian$ adb -bash: adb: command not found briandeMacBook-Pro:~ brian ...
- Mysql 索引精讲
Mysql 索引精讲 开门见山,直接上图,下面的思维导图即是现在要讲的内容,可以先有个印象- 常见索引类型(实现层面) 索引种类(应用层面) 聚簇索引与非聚簇索引 覆盖索引 最佳索引使用策略 1.常见 ...
- Linux--简单实现nfs的目录挂载,ntp时间同步
一.NFS (Network FileSystem) 网络文件系统 是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源. 在NFS的应用中,本地NFS的客户端 ...
- VM虚拟机Android安装图形界面
摘自,转 https://blog.csdn.net/weixin_42633191/article/details/89391188
- Jmeter之命令行生成HTML报告
其实每次使用jemter.bat文件启动JMeter时,命令行窗口都会提示我们不要使用GUI窗口进行测试,除非是进行调试脚本 使用命令行生成结果也很测试报告也很简单 jmeter -n -t [jmx ...
- 挂载system.img并提取文件
今天提取线刷包的system.img出来,使用Mount命令挂载 $ sudo mount -t ext4 -o loop system.img /mnt mount: 文件系统类型错误.选项错误./ ...
- coco数据集标注图转为二值图python(附代码)
coco数据集大概有8w张以上的图片,而且每幅图都有精确的边缘mask标注. 后面后分享一个labelme标注的json或xml格式转二值图的源码(以备以后使用) 而我现在在研究显著性目标检测,需要的 ...
- 创建testng.xml文件
简单介绍 运行TestNG测试脚本有两种方式:一种是直接通过IDE运行(例如使用eclipse中的“Run TestNG tests”),另一种是从命令行运行(通过使用xml配置文件).当我们想执行某 ...
- 不获取元素,直接使用id操作dom元素
今天无意中发现个让我很吃惊的问题. 不使用getElementById方法,也可以用id直接操作有id的元素. 继续搜索后,发现name也可以直接操作... 这让我大感意外,了解以后,忍不住写点东西记 ...