WPF自定义控件和样式之自定义按钮(Button)
一、前言
程序界面上的按钮多种多样,常用的就这几种:普通按钮、图标按钮、文字按钮、图片文字混合按钮。本文章记录了不同样式类型的按钮实现方法。下面话不多说了,来一起看看详细的介绍吧。
二、固定样式的按钮
固定样式的按钮一般在临时使用时或程序的样式比较固定时才会使用,按钮整体样式不需要做大的改动。
2.1 普通按钮-扁平化风格
先看效果:
定义Button的样式,详见代码:
<Style x:Key="BtnInfoStyle" TargetType="Button"> <Setter Property="Width" Value="70"/> <Setter Property="Height" Value="25"/> <Setter Property="Foreground" Value="White"/> <Setter Property="BorderThickness" Value="0"/> <Setter Property="Background" Value="#43a9c7"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True"> <TextBlock Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="border" Property="Background" Value="#2f96b4"/> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter TargetName="border" Property="Background" Value="#2a89a4"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
引用方法:
<Grid Background="White"> <StackPanel Orientation="Horizontal" Margin="10" VerticalAlignment="Top"> <Button Style="{StaticResource BtnInfoStyle}" Content="信息" Margin="5 0"/> </Grid>
上述代码实现了Button按钮的扁平化样式,如果你想调整颜色风格,通过修改Background的值可实现默认颜色,鼠标经过颜色以及鼠标按下颜色。
2.2 图标按钮
先看效果:
Button样式的代码和扁平化Button差不多,只是把TextBlock控件替换成了Image控件,另外需要设置Button默认的背景色为透明。废话不多说看代码:
<Style x:Key="BtnImageStyle1" TargetType="Button"> <Setter Property="Cursor" Value="Hand"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"> <Image x:Name="Img" VerticalAlignment="Center" HorizontalAlignment="Center" Source="/Images/button1.png" Stretch="None"/> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="Img" Property="Source" Value="/Images/button1.png"/> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter TargetName="Img" Property="Source" Value="/Images/button1.png"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
这里的button1.png需要自己准备图片资源,IsMouseOver和IsPressed的图片资源可自己替换,替换之后能有更丰富的效果呈现。
2.3 图标文字混合按钮
效果:
实现代码:
<Style x:Key="BtnImgTxtStyle1" TargetType="Button"> <Setter Property="Foreground" Value="#555"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <Image Source="Images/adshut.png" Stretch="None"/> <TextBlock x:Name="Txt" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/> </StackPanel> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Foreground" Value="#333333" TargetName="Txt"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
2.4 文字按钮和2.3中的图标文字按钮样式差不多,只需要把Image控件去掉就行。
三、复用性高的按钮
要想实现复用性高的按钮,就必须新建自定义控件。下面这个实例通过自定义控件实现上述所有效果,并且可以随意更改风格。
首先在项目中右键-添加-新建项-自定义控件。
新建自定义控件之后,添加依赖属性。代码如下:
public class ButtonEx : Button { static ButtonEx() { DefaultStyleKeyProperty.OverrideMetadata(typeof(ButtonEx), new FrameworkPropertyMetadata(typeof(ButtonEx))); } public ButtonType ButtonType { get { return (ButtonType)GetValue(ButtonTypeProperty); } set { SetValue(ButtonTypeProperty, value); } } public static readonly DependencyProperty ButtonTypeProperty = DependencyProperty.Register("ButtonType", typeof(ButtonType), typeof(ButtonEx), new PropertyMetadata(ButtonType.Normal)); public ImageSource Icon { get { return (ImageSource)GetValue(IconProperty); } set { SetValue(IconProperty, value); } } public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(ImageSource), typeof(ButtonEx), new PropertyMetadata(null)); public CornerRadius CornerRadius { get { return (CornerRadius)GetValue(CornerRadiusProperty); } set { SetValue(CornerRadiusProperty, value); } } public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(ButtonEx), new PropertyMetadata(new CornerRadius(0))); public Brush MouseOverForeground { get { return (Brush)GetValue(MouseOverForegroundProperty); } set { SetValue(MouseOverForegroundProperty, value); } } public static readonly DependencyProperty MouseOverForegroundProperty = DependencyProperty.Register("MouseOverForeground", typeof(Brush), typeof(ButtonEx), new PropertyMetadata()); public Brush MousePressedForeground { get { return (Brush)GetValue(MousePressedForegroundProperty); } set { SetValue(MousePressedForegroundProperty, value); } } public static readonly DependencyProperty MousePressedForegroundProperty = DependencyProperty.Register("MousePressedForeground", typeof(Brush), typeof(ButtonEx), new PropertyMetadata()); public Brush MouseOverBorderbrush { get { return (Brush)GetValue(MouseOverBorderbrushProperty); } set { SetValue(MouseOverBorderbrushProperty, value); } } public static readonly DependencyProperty MouseOverBorderbrushProperty = DependencyProperty.Register("MouseOverBorderbrush", typeof(Brush), typeof(ButtonEx), new PropertyMetadata()); public Brush MouseOverBackground { get { return (Brush)GetValue(MouseOverBackgroundProperty); } set { SetValue(MouseOverBackgroundProperty, value); } } public static readonly DependencyProperty MouseOverBackgroundProperty = DependencyProperty.Register("MouseOverBackground", typeof(Brush), typeof(ButtonEx), new PropertyMetadata()); public Brush MousePressedBackground { get { return (Brush)GetValue(MousePressedBackgroundProperty); } set { SetValue(MousePressedBackgroundProperty, value); } } public static readonly DependencyProperty MousePressedBackgroundProperty = DependencyProperty.Register("MousePressedBackground", typeof(Brush), typeof(ButtonEx), new PropertyMetadata()); } public enum ButtonType { Normal, Icon, Text, IconText }
为不同类型按钮设置样式,代码如下:
<Style TargetType="{x:Type local:ButtonEx}"> <Style.Triggers> <Trigger Property="ButtonType" Value="Normal"> <Setter Property="Background" Value="#43a9c7"/> <Setter Property="MouseOverBackground" Value="#2f96b4"/> <Setter Property="MousePressedBackground" Value="#2a89a4"/> <Setter Property="Foreground" Value="White"/> <Setter Property="MouseOverForeground" Value="White"/> <Setter Property="MousePressedForeground" Value="White"/> <Setter Property="BorderBrush" Value="Transparent"/> <Setter Property="BorderThickness" Value="0"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:ButtonEx}"> <Border x:Name="border" Background="{TemplateBinding Background}" CornerRadius="{TemplateBinding CornerRadius}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" SnapsToDevicePixels="True"> <TextBlock x:Name="txt" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="border" Property="Background" Value="{Binding MouseOverBackground,RelativeSource={RelativeSource TemplatedParent}}"/> <Setter TargetName="txt" Property="Foreground" Value="{Binding MouseOverForeground,RelativeSource={RelativeSource TemplatedParent}}"/> <Setter TargetName="border" Property="BorderBrush" Value="{Binding MouseOverBorderbrush,RelativeSource={RelativeSource TemplatedParent}}"/> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter TargetName="border" Property="Background" Value="{Binding MousePressedBackground,RelativeSource={RelativeSource TemplatedParent}}"/> <Setter TargetName="txt" Property="Foreground" Value="{Binding MousePressedForeground,RelativeSource={RelativeSource TemplatedParent}}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Trigger> <Trigger Property="ButtonType" Value="Icon"> <Setter Property="Cursor" Value="Hand"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:ButtonEx}"> <Border Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"> <Image x:Name="Img" VerticalAlignment="Center" HorizontalAlignment="Center" Source="{TemplateBinding Icon}" Stretch="None"/> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Opacity" Value="0.8"/> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="Opacity" Value="0.9"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Trigger> <Trigger Property="ButtonType" Value="Text"> <Setter Property="Cursor" Value="Hand"/> <Setter Property="Foreground" Value="#002c99"/> <Setter Property="MouseOverForeground" Value="#FF2c99"/> <Setter Property="MousePressedForeground" Value="#002c99"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:ButtonEx}"> <TextBlock x:Name="txt" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Foreground" Value="{Binding MouseOverForeground,RelativeSource={RelativeSource TemplatedParent}}" TargetName="txt"/> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="Foreground" Value="{Binding MousePressedForeground,RelativeSource={RelativeSource TemplatedParent}}" TargetName="txt"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Trigger> <Trigger Property="ButtonType" Value="IconText"> <Setter Property="Cursor" Value="Hand"/> <Setter Property="Foreground" Value="#555"/> <Setter Property="MouseOverForeground" Value="#555"/> <Setter Property="MousePressedForeground" Value="#555"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:ButtonEx}"> <Border> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <Image Source="{TemplateBinding Icon}" Stretch="None"/> <TextBlock x:Name="Txt" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/> </StackPanel> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Foreground" Value="{Binding MouseOverForeground,RelativeSource={RelativeSource TemplatedParent}}" TargetName="Txt"/> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="Foreground" Value="{Binding MousePressedForeground,RelativeSource={RelativeSource TemplatedParent}}" TargetName="Txt"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Trigger> </Style.Triggers> </Style>
然后就可以引用该控件了:
<Grid> <WrapPanel> <local:ButtonEx Content="信息" Width="75" Height="25" Margin="10" ButtonType="Normal"/> <local:ButtonEx Icon="/Images/button1.png" Margin="10" ButtonType="Icon"/> <local:ButtonEx Content="文字按钮" Margin="10" ButtonType="Text"/> <local:ButtonEx Content="图文按钮" Icon="/Images/adshut.png" Margin="10" ButtonType="IconText"/> </WrapPanel> </Grid>
效果如下:
至此已经完成Button控件的扩展功能,如果想要添加动画或者设置图标的位置和边距等,可以自己另外添加依赖属性来扩展。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。
- React Native库版本升级与降级
- Java并发学习之Volatile及内存模型探究
- Java并发学习之CountDownLatch实现原理及使用姿势
- Linux基础(day58)
- 携程Android App插件化和动态加载实践
- 15.5 使用pure-ftpd搭建ftp服务
- JDK容器学习之Queue: ArrayBlockingQueue
- 手机APP安装包缩减方案
- react-native添加redux支持
- Java并发学习之ReentrantLock的工作原理及使用姿势
- Linux基础(day63)
- IOS WebView控件详解
- Java并发学习之synchronized使用小结
- 18.3/18.4/18.5 用keepalived配置高可用集群
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Gradle 命令行介紹和安裝教程
- Spring工厂创建复杂对象
- Nginx反向代理配置去除前缀
- 深入浅出java虚拟机
- Maven resources 分环境
- JetBrains Upsource(上源) 研究
- Spring JPA 拓展
- python自学成才之路 死锁的解决方案
- C++核心准则T.40: 使用函数对象向算法传递操作
- web页面性能优化总结及原理解释
- C++核心准则T.41:在模板概念中只对本质属性定义需求
- Linux实用技巧——mail发送邮件命令以及中文乱码解决
- Julia机器学习实战——使用Random Forest随机森林进行字符图像识别
- Python函数——Numpy size()
- Day 1:二维数组中查找