三、自定义Button模板触发器(纯XAML)
需求:
①做一个带有圆角的Button,宽300高100,内容是custom_btn,背景颜色为青色,最外边是红色且线宽8;
②鼠标移动到按钮上(IsMouseOver),字体放大为50且背景颜色变为紫色(#800080)
③鼠标点击按钮(IsPressed),背景颜色变为橙色(#ffb100)
一、新建项目
新建一个窗口,例如:
在App.xaml中设置该页面为启动页面
二、绘制button
①做一个带有圆角的Button,宽300高100,内容是custom_btn,背景颜色为青色,最外边是红色且线宽8;
Ⅰ,布置外观
宽300 Width="300"
高100 Height="100"
内容是custom_btn Content="custom_btn"
背景颜色为青色 Background="Cyan"
最外边是红色且线宽8 BorderBrush="Red" BorderThickness="8"
<Button Width="300" Height="100" Content="custom_btn" Background="Cyan" BorderBrush="Red" BorderThickness="8" ></Button>
Ⅱ,设置模板
按钮模板:我们要做一个button的模板,需要使用Button.Template
属性重新定义按钮的视觉外观,再通过ControlTemplate
指定模板应用于Button
类型
当我们写到这里的时候,系统知道我们要重新自定义button了,所有的button原先的样式全部消失
<Button Width="300" Height="100" Background="Cyan" BorderBrush="Red" BorderThickness="8" ><Button.Template><ControlTemplate TargetType="{x:Type Button}"></ControlTemplate></Button.Template>
</Button>
Ⅲ,使用Border控件显示圆角
边框元素:因为需求是一个带有圆角的button,故Border
元素作为按钮的视觉根元素,CornerRadius="50"
使边框变为椭圆形
使用TemplateBinding
将模板属性绑定到按钮的实际属性
给Border起个名称x:Name="border"
,后续触发需要用到
<Button Width="300" Height="100" Background="Cyan" BorderBrush="Red" BorderThickness="8" ><Button.Template><ControlTemplate TargetType="{x:Type Button}"><Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="50"></Border></ControlTemplate></Button.Template>
</Button>
Ⅳ,通过显示内容
方法一:通过ContentPresenter
使用原本的的Button的属性
但是该方法很局限,没办法再次自定义
<Button Width="300" Height="100" Content="custom_btn" Background="Cyan" BorderBrush="Red" BorderThickness="8" Click="Button_Click" ><Button.Template><ControlTemplate TargetType="{x:Type Button}"><Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="50"><ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/></Border></ControlTemplate></Button.Template>
</Button>
方法二:使用TextBlock
控件显示内容(推荐)
给TextBlock控件起个名称x:Name="txtContent"
,后续触发需要用到
<Button Width="300" Height="100" Content="custom_btn" Background="Cyan" BorderBrush="Red" BorderThickness="8" Click="Button_Click" ><Button.Template><ControlTemplate TargetType="{x:Type Button}"><Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="50"><TextBlock x:Name="txtContent" Text="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/></Border></ControlTemplate></Button.Template>
</Button>
三、鼠标移动事件触发
②鼠标移动到按钮上(IsMouseOver),字体放大为50且背景颜色变为紫色(#800080)
通过ontrolTemplate.Triggers
的Trigger
进行绑定事件
<Trigger Property="IsMouseOver" Value="True">
鼠标是否移动在该控件上,True表示在,False表示不在
<Setter TargetName="border" Property="Background" Value="#800080"/>
设置背景颜色
<Setter TargetName="txtContent" Property="FontSize" Value="50"/>
设置字体
<Button Width="300" Height="100" Content="custom_btn" Background="Cyan" BorderBrush="Red" BorderThickness="8" ><Button.Template><ControlTemplate TargetType="{x:Type Button}"><Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="50"><TextBlock x:Name="txtContent" Text="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/></Border><ControlTemplate.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter TargetName="border" Property="Background" Value="#800080"/><Setter TargetName="txtContent" Property="FontSize" Value="50"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Button.Template>
</Button>
四、鼠标点击事件触发
③鼠标点击按钮(IsPressed),背景颜色变为橙色(#ffb100)
同理,<Trigger Property="IsPressed" Value="True">
控件是否按下,True表示按下,False表示未按下
<Setter TargetName="border" Property="Background" Value="#ffb100"/>
设置背景颜色
<Button Width="300" Height="100" Content="custom_btn" Background="Cyan" BorderBrush="Red" BorderThickness="8" ><Button.Template><ControlTemplate TargetType="{x:Type Button}"><Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="50"><TextBlock x:Name="txtContent" Text="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/></Border><ControlTemplate.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter TargetName="border" Property="Background" Value="#800080"/><Setter TargetName="txtContent" Property="FontSize" Value="50"/></Trigger><Trigger Property="IsPressed" Value="True"><Setter TargetName="border" Property="Background" Value="#ffb100"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Button.Template>
</Button>
五、完整代码
<Window x:Class="WpfApp1.custom_button"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfApp1"mc:Ignorable="d"Title="custom_button" Height="450" Width="800"><Grid><Button Width="300" Height="100" Content="custom_btn" Background="Cyan" BorderBrush="Red" BorderThickness="8" Click="Button_Click" ><Button.Template><ControlTemplate TargetType="{x:Type Button}"><Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="50"><TextBlock x:Name="txtContent" Text="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/></Border><ControlTemplate.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter TargetName="border" Property="Background" Value="Purple"/><Setter TargetName="txtContent" Property="FontSize" Value="50"/></Trigger><Trigger Property="IsPressed" Value="True"><Setter TargetName="border" Property="Background" Value="#ffb100"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Button.Template></Button></Grid>
</Window>
六、效果展示
自定义Button
鼠标移动
鼠标点击
七、总结
1. Button元素属性
- Width=“300” - 设置按钮宽度为300设备无关单位
- Height=“100” - 设置按钮高度为100设备无关单位
- Content=“custom_btn” - 设置按钮显示的文本内容
- Background=“Cyan” - 设置按钮背景颜色为青色
- BorderBrush=“Red” - 设置按钮边框颜色为红色
- BorderThickness=“8” - 设置按钮边框厚度为8单位
2. Button.Template元素
- 定义按钮的视觉模板,完全重写按钮的默认外观
3. ControlTemplate元素
- TargetType=“{x:Type Button}” - 指定此模板应用于Button类型的控件
4. Border元素
- x:Name=“border” - 为边框元素命名,便于在触发器中引用
- Background=“{TemplateBinding Background}” - 将边框背景绑定到按钮的Background属性
- BorderBrush=“{TemplateBinding BorderBrush}” - 将边框颜色绑定到按钮的BorderBrush属性
- BorderThickness=“{TemplateBinding BorderThickness}” - 将边框厚度绑定到按钮的BorderThickness属性
- CornerRadius=“50” - 设置边框圆角半径为50,使按钮呈现椭圆形外观
5. TextBlock元素
- x:Name=“txtContent” - 为文本元素命名,便于在触发器中引用
- Text=“{TemplateBinding Content}” - 将文本内容绑定到按钮的Content属性
- HorizontalAlignment=“Center” - 文本水平居中对齐
- VerticalAlignment=“Center” - 文本垂直居中对齐
6. ControlTemplate.Triggers元素
- 包含模板的触发器集合,用于定义按钮在不同状态下的视觉变化
7. Trigger元素 (IsMouseOver)
- Property=“IsMouseOver” - 监听IsMouseOver属性变化
- Value=“True” - 当属性值为True时激活触发器
- 内部Setter元素:
- TargetName=“border” - 指定要修改的元素名为"border"
- Property=“Background” - 要修改的属性是Background
- Value=“#800080” - 将背景色设置为深紫色(#800080)
- TargetName=“txtContent” - 指定要修改的元素名为"txtContent"
- Property=“FontSize” - 要修改的属性是FontSize
- Value=“50” - 将字体大小设置为50
8. Trigger元素 (IsPressed)
- Property=“IsPressed” - 监听IsPressed属性变化
- Value=“True” - 当属性值为True时激活触发器
- 内部Setter元素:
- TargetName=“border” - 指定要修改的元素名为"border"
- Property=“Background” - 要修改的属性是Background
- Value=“#ffb100” - 将背景色设置为橙色(#ffb100)
功能总结
这个自定义按钮模板实现了以下功能:
- 创建了一个椭圆形按钮(通过CornerRadius=“50”)
- 保持了与原始按钮属性的绑定(使用TemplateBinding)
- 添加了鼠标悬停效果:背景变紫色,文字变大
- 添加了按下效果:背景变橙色
这种自定义模板的方式允许开发者完全控制按钮的外观,同时保留按钮的所有功能和行为。