WPF自定义控件(一)——Button
接触WPF也有两个多月了,有了一定的理论基础和项目经验,现在打算写一个系列,做出来一个WPF的控件库。一方面可以加强自己的水平,另一方面可以给正在学习WPF的同行一个参考。本人水平有限,难免有一些错误,望各位指出!
先上图看看各种效果:
这个Button是我继承系统Button后扩展的,主要实现了:可设置悬浮和按下时的背景,可改变形状,并可设置按钮按下后保持锁定状态等功能。
这个Button我命名为XButton,扩展的所有属性我都会以X开头命名。好了,具体的东西看代码吧!
先来Xaml的:
- <ResourceDictionary
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:ctrl="clr-namespace:KAN.WPF.XCtrl.Controls">
- <Style x:Key="{x:Type ctrl:XButton}" TargetType="{x:Type ctrl:XButton}">
- <Style.Resources>
- <ResourceDictionary Source="/KAN.WPF.Xctrl;component/Themes/CommonStyle.xaml"/>
- </Style.Resources>
- <Setter Property="FocusVisualStyle" Value="{StaticResource StyleFocusVisual}"/>
- <Setter Property="Background" Value="White"/>
- <Setter Property="BorderBrush" Value="Silver"/>
- <Setter Property="BorderThickness" Value="1"/>
- <Setter Property="Control.Template">
- <Setter.Value>
- <ControlTemplate TargetType="{x:Type ctrl:XButton}">
- <!--定义视觉树-->
- <Grid>
- <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
- <!--这里的Path就是用来实现各种外形的-->
- <Path x:Name="bdrButton"
- Data="{Binding XShape, RelativeSource={RelativeSource TemplatedParent}}"
- Stroke="{Binding XStrokeBrush, RelativeSource={RelativeSource TemplatedParent}}"
- StrokeThickness="{Binding XStrokeThickness, RelativeSource={RelativeSource TemplatedParent}}"
- Stretch="Fill" RenderTransformOrigin="0.5,0.5" Fill="{TemplateBinding Control.Background}">
- <Path.RenderTransform>
- <TransformGroup>
- <ScaleTransform/>
- <SkewTransform/>
- <RotateTransform/>
- <TranslateTransform/>
- </TransformGroup>
- </Path.RenderTransform>
- </Path>
- </Border>
- <ContentPresenter Name="contentPresenter" ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
- ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" Focusable="False" RecognizesAccessKey="True"
- SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" Content="{TemplateBinding ContentControl.Content}"
- HorizontalAlignment="Center" VerticalAlignment="Center" />
- </Grid>
- <!--设置触发器-->
- <ControlTemplate.Triggers>
- <!--鼠标移动上去时-->
- <Trigger Property="UIElement.IsMouseOver" Value="True" >
- <Setter TargetName="bdrButton" Value="{Binding XMoverBrush, RelativeSource={RelativeSource TemplatedParent}}" Property="Path.Fill" />
- </Trigger>
- <!--鼠标按下去时-->
- <Trigger Property="ButtonBase.IsPressed" Value="True">
- <Setter TargetName="bdrButton" Value="{Binding XEnterBrush, RelativeSource={RelativeSource TemplatedParent}}" Property="Path.Fill" />
- </Trigger>
- <!--禁用Button时-->
- <Trigger Property="IsEnabled" Value="false">
- <Setter TargetName="bdrButton" Value="{Binding XUnEnabledBrush, RelativeSource={RelativeSource TemplatedParent}}" Property="Path.Fill" />
- </Trigger>
- <!--如果设置了锁住按下的状态的属性,那么当按下时-->
- <MultiTrigger>
- <MultiTrigger.Conditions>
- <Condition Property="IsFocused" Value="True"/>
- <Condition Property="XIsFoucedBrushLock" Value="True"/>
- </MultiTrigger.Conditions>
- <MultiTrigger.Setters>
- <Setter TargetName="bdrButton" Value="{Binding XEnterBrush, RelativeSource={RelativeSource TemplatedParent}}" Property="Path.Fill" />
- </MultiTrigger.Setters>
- </MultiTrigger>
- </ControlTemplate.Triggers>
- </ControlTemplate>
- </Setter.Value>
- </Setter>
- </Style>
- </ResourceDictionary>
其中的StyleFocusVisual是用来定义按Tab到这个控件上的样式的,代码如下:
- <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
- <Style x:Key="StyleFocusVisual">
- <Setter Property="Control.Template">
- <Setter.Value>
- <ControlTemplate>
- <Border Margin="0" BorderBrush="#FF9FBDF4" BorderThickness="1"/>
- </ControlTemplate>
- </Setter.Value>
- </Setter>
- </Style>
- </ResourceDictionary>
接下来是CS的:
- using System;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Media;
- using System.Windows.Shapes;
- using System.Windows.Media.Imaging;
- namespace KAN.WPF.XCtrl.Controls
- {
- /// <summary>
- /// 扩展按钮:可设置悬浮和按下时的背景,可改变形状,并可设置按钮按下后保持锁定状态
- /// </summary>
- public class XButton : Button
- {
- #region 依赖属性
- public static readonly DependencyProperty XMoverBrushProperty;//鼠标经过时的画刷
- public static readonly DependencyProperty XEnterBrushProperty;//鼠标按下时的画刷
- public static readonly DependencyProperty XUnEnabledBrushProperty;//禁用时的画刷
- public static readonly DependencyProperty XIsFoucedBrushLockProperty;//是否得到焦点时锁住画刷
- public static readonly DependencyProperty XShapeProperty;//外形的路径
- public static readonly DependencyProperty XStrokeBrushProperty;//外形的路径着色
- public static readonly DependencyProperty XStrokeThicknessProperty;//外形的路径粗细(默认为0,因为有Border边框,所以要设这个值,要先把BorderThickness设为0)
- #endregion
- #region 内部方法
- /// <summary>
- /// 静态构造方法
- /// </summary>
- static XButton()
- {
- //注册依赖属性
- XButton.XMoverBrushProperty = DependencyProperty.Register("XMoverBrush", typeof(Brush), typeof(XButton),
- new PropertyMetadata(Brushes.WhiteSmoke));
- XButton.XEnterBrushProperty = DependencyProperty.Register("XEnterBrush", typeof(Brush), typeof(XButton),
- new PropertyMetadata(Brushes.Silver));
- XButton.XUnEnabledBrushProperty = DependencyProperty.Register("XUnEnabledBrush", typeof(Brush), typeof(XButton),
- new PropertyMetadata(Brushes.Silver));
- XButton.XStrokeBrushProperty = DependencyProperty.Register("XStrokeBrush", typeof(Brush), typeof(XButton),
- new PropertyMetadata(Brushes.Silver));
- XButton.XStrokeThicknessProperty = DependencyProperty.Register("XStrokeThickness", typeof(Double), typeof(XButton),
- new PropertyMetadata(0.0));
- XButton.XIsFoucedBrushLockProperty = DependencyProperty.Register("XIsFoucedBrushLock", typeof(bool), typeof(XButton),
- new PropertyMetadata(false));
- XButton.XShapeProperty = DependencyProperty.Register("XShape", typeof(string), typeof(XButton),
- new PropertyMetadata("M 0 0 L 0 0 L 100 0 L 100 100 L 0 100 Z"));
- FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(XButton), new FrameworkPropertyMetadata(typeof(XButton)));
- }
- #endregion
- #region 公布属性
- /// <summary>
- /// 公布属性XMoverBrush(鼠标经过时的画刷)
- /// </summary>
- public Brush XMoverBrush
- {
- get
- {
- return base.GetValue(XButton.XMoverBrushProperty) as Brush;
- }
- set
- {
- base.SetValue(XButton.XMoverBrushProperty, value);
- }
- }
- /// <summary>
- /// 公布属性XMoverBrush(鼠标按下时的画刷)
- /// </summary>
- public Brush XEnterBrush
- {
- get
- {
- return base.GetValue(XButton.XEnterBrushProperty) as Brush;
- }
- set
- {
- base.SetValue(XButton.XEnterBrushProperty, value);
- }
- }
- /// <summary>
- /// 公布属性XUnEnabledBrush(禁用时的画刷)
- /// </summary>
- public Brush XUnEnabledBrush
- {
- get
- {
- return base.GetValue(XButton.XUnEnabledBrushProperty) as Brush;
- }
- set
- {
- base.SetValue(XButton.XUnEnabledBrushProperty, value);
- }
- }
- /// <summary>
- /// 公布属性XIsFoucedBrushLock(是否得到焦点时锁住画刷)
- /// </summary>
- public bool XIsFoucedBrushLock
- {
- get
- {
- return (bool)base.GetValue(XButton.XIsFoucedBrushLockProperty);
- }
- set
- {
- base.SetValue(XButton.XIsFoucedBrushLockProperty, value);
- }
- }
- /// <summary>
- /// 公布属性XShape(外形的路径)
- /// </summary>
- public String XShape
- {
- get
- {
- return base.GetValue(XButton.XShapeProperty) as String;
- }
- set
- {
- base.SetValue(XButton.XShapeProperty, value);
- }
- }
- /// <summary>
- /// 公布属性XStrokeBrush(外形的路径着色)
- /// </summary>
- public Brush XStrokeBrush
- {
- get
- {
- return base.GetValue(XButton.XStrokeBrushProperty) as Brush;
- }
- set
- {
- base.SetValue(XButton.XStrokeBrushProperty, value);
- }
- }
- /// <summary>
- /// 公布属性XStrokeThickness(外形的路径粗细)
- /// </summary>
- public Double XStrokeThickness
- {
- get
- {
- return (Double)base.GetValue(XButton.XStrokeThicknessProperty);
- }
- set
- {
- base.SetValue(XButton.XStrokeThicknessProperty, value);
- }
- }
- #endregion
- }
- }
看了代码上的注释应该都能明白吧!要是有不明白的可以留言。
至于源代码,我之后会整理几个控件后一起发上来的!
WPF自定义控件(一)——Button的更多相关文章
- WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展
一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要是对文本 ...
- WPF自定义控件与样式(2)-自定义按钮FButton
一.前言.效果图 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 还是先看看效果 ...
- WPF自定义控件与样式(15)-终结篇 & 系列文章索引 & 源码共享
系列文章目录 WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与样式(3)-TextBox & Ric ...
- WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 日历控 ...
- WPF自定义控件与样式(15)-终结篇
原文:WPF自定义控件与样式(15)-终结篇 系列文章目录 WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与 ...
- WPF自定义控件创建
WPF自定义控件创建 本文简单的介绍一下WPF自定义控件的开发. 首先,我们打开VisualStudio创建一个WPF自定义控件库,如下图: 然后,我们可以看到创建的解决方案如下: 在解决方案中,我们 ...
- WPF自定义控件(三)の扩展控件
扩展控件,顾名思义就是对已有的控件进行扩展,一般继承于已有的原生控件,不排除继承于自定义的控件,不过这样做意义不大,因为既然都自定义了,为什么不一步到位呢,有些不同的需求也可以通过此来完成,不过类似于 ...
- WPF自定义控件(二)の重写原生控件样式模板
话外篇: 要写一个圆形控件,用Clip,重写模板,去除样式引用圆形图片可以有这三种方式. 开发过程中,我们有时候用WPF原生的控件就能实现自己的需求,但是样式.风格并不能满足我们的需求,那么我们该怎么 ...
- WPF自定义控件(一)の控件分类
一.什么是控件(Controls) 控件是指对数据和方法的封装.控件可以有自己的属性和方法,其中属性是控件数据的简单访问者,方法则是控件的一些简单而可见的功能.控件创建过程包括设计.开发.调试(就是所 ...
- 【转】WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要内容: 日历控件Calendar自定义样式: 日期控件DatePicker自定 ...
随机推荐
- HDU1213
http://acm.split.hdu.edu.cn/showproblem.php?pid=1213 #include<stdio.h> #include<algorithm&g ...
- 利用UDP19端口实施DOS攻击的真实案例
昨天在一个用户现场发现了一个利用UDP19端口对互联网受害者主机进行DOS攻击的真实案例.这个情况是我第一次见到,个人认为对以后遇到此类情况的兄弟具有参考价值.有必要做一个简单的分析记录. 在此次的分 ...
- android界面布局技巧(一)
(1)//得到手机的宽高 Display display = getWindowManager().getDefaultDisplay(); int screenWidth = display.get ...
- Flask框架学习笔记(API接口管理平台 V1.0)
今天博主终于完成了API接口管理平台,最后差的就是数据库的维护, 博主这里介绍下平台的设计原理,首先基于python,利用flask的web框架+bootstrap前端框架完成,先阶段完成了前台展示页 ...
- git克隆项目到一个非空目录
这只是记录: 1. 进入非空目录,假设是 /workdir/proj1 2. git clone --no-checkout https://git.oschina.net/NextApp/platf ...
- 【CImg】简单的畸变矩形矫正
三个角点确定一个平面,畸变的平面可以看成是不同基底下同一图像的表示 ============================我是分割线============================= 1. ...
- Android开发-API指南-<instrumentation >
<instrumentation> 英文原文:http://developer.android.com/guide/topics/manifest/instrumentation-elem ...
- Swift学习—字符串&数组&字典
字符串 OC和Swift中字符串的区别 在OC中字符串类型时NSString,在Swift中字符串类型是String OC中字符串@"",Swift中字符串"" ...
- rsync安装使用
安装 yum install rsync mkdir /etc/rsyncd cd /etc/rsyncd vi rsyncd.conf pid file = /var/run/rsyncd.pid ...
- SQL where 1=1的作用
浅谈where 1=1 1.简单理解的话where 1=1 永真, where 1<>1 永假 2.1<>1 的用处: 用于只取结构不取数据的场合 例如: ...