首页 > 代码库 > WPF自定义控件(一)——Button
WPF自定义控件(一)——Button
接触WPF也有两个多月了,有了一定的理论基础和项目经验,现在打算写一个系列,做出来一个WPF的控件库。一方面可以加强自己的水平,另一方面可以给正在学习WPF的同行一个参考。本人水平有限,难免有一些错误,望各位指出!
先上图看看各种效果:
这个Button是我继承系统Button后扩展的,主要实现了:可设置悬浮和按下时的背景,可改变形状,并可设置按钮按下后保持锁定状态等功能。
这个Button我命名为XButton,扩展的所有属性我都会以X开头命名。好了,具体的东西看代码吧!
先来Xaml的:
1 <ResourceDictionary 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:ctrl="clr-namespace:KAN.WPF.XCtrl.Controls"> 5 <Style x:Key="{x:Type ctrl:XButton}" TargetType="{x:Type ctrl:XButton}"> 6 <Style.Resources> 7 <ResourceDictionary Source="/KAN.WPF.Xctrl;component/Themes/CommonStyle.xaml"/> 8 </Style.Resources> 9 <Setter Property="FocusVisualStyle" Value="{StaticResource StyleFocusVisual}"/>10 <Setter Property="Background" Value="White"/>11 <Setter Property="BorderBrush" Value="Silver"/>12 <Setter Property="BorderThickness" Value="1"/>13 <Setter Property="Control.Template">14 <Setter.Value>15 <ControlTemplate TargetType="{x:Type ctrl:XButton}">16 <!--定义视觉树-->17 <Grid>18 <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">19 <!--这里的Path就是用来实现各种外形的-->20 <Path x:Name="bdrButton"21 Data="{Binding XShape, RelativeSource={RelativeSource TemplatedParent}}" 22 Stroke="{Binding XStrokeBrush, RelativeSource={RelativeSource TemplatedParent}}"23 StrokeThickness="{Binding XStrokeThickness, RelativeSource={RelativeSource TemplatedParent}}"24 Stretch="Fill" RenderTransformOrigin="0.5,0.5" Fill="{TemplateBinding Control.Background}">25 <Path.RenderTransform>26 <TransformGroup>27 <ScaleTransform/>28 <SkewTransform/>29 <RotateTransform/>30 <TranslateTransform/>31 </TransformGroup>32 </Path.RenderTransform>33 </Path>34 </Border>35 <ContentPresenter Name="contentPresenter" ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" 36 ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" Focusable="False" RecognizesAccessKey="True" 37 SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" Content="{TemplateBinding ContentControl.Content}" 38 HorizontalAlignment="Center" VerticalAlignment="Center" />39 </Grid>40 <!--设置触发器-->41 <ControlTemplate.Triggers>42 <!--鼠标移动上去时-->43 <Trigger Property="UIElement.IsMouseOver" Value="True" >44 <Setter TargetName="bdrButton" Value="{Binding XMoverBrush, RelativeSource={RelativeSource TemplatedParent}}" Property="Path.Fill" />45 </Trigger>46 <!--鼠标按下去时-->47 <Trigger Property="ButtonBase.IsPressed" Value="True">48 <Setter TargetName="bdrButton" Value="{Binding XEnterBrush, RelativeSource={RelativeSource TemplatedParent}}" Property="Path.Fill" />49 </Trigger>50 <!--禁用Button时-->51 <Trigger Property="IsEnabled" Value="false">52 <Setter TargetName="bdrButton" Value="{Binding XUnEnabledBrush, RelativeSource={RelativeSource TemplatedParent}}" Property="Path.Fill" />53 </Trigger>54 <!--如果设置了锁住按下的状态的属性,那么当按下时-->55 <MultiTrigger>56 <MultiTrigger.Conditions>57 <Condition Property="IsFocused" Value="True"/>58 <Condition Property="XIsFoucedBrushLock" Value="True"/>59 </MultiTrigger.Conditions>60 <MultiTrigger.Setters>61 <Setter TargetName="bdrButton" Value="{Binding XEnterBrush, RelativeSource={RelativeSource TemplatedParent}}" Property="Path.Fill" />62 </MultiTrigger.Setters>63 </MultiTrigger>64 </ControlTemplate.Triggers>65 </ControlTemplate>66 </Setter.Value>67 </Setter>68 </Style>69 </ResourceDictionary>
其中的StyleFocusVisual是用来定义按Tab到这个控件上的样式的,代码如下:
1 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 2 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 3 <Style x:Key="StyleFocusVisual"> 4 <Setter Property="Control.Template"> 5 <Setter.Value> 6 <ControlTemplate> 7 <Border Margin="0" BorderBrush="#FF9FBDF4" BorderThickness="1"/> 8 </ControlTemplate> 9 </Setter.Value>10 </Setter>11 </Style>12 </ResourceDictionary>
接下来是CS的:
1 using System; 2 using System.Windows; 3 using System.Windows.Controls; 4 using System.Windows.Media; 5 using System.Windows.Shapes; 6 using System.Windows.Media.Imaging; 7 8 namespace KAN.WPF.XCtrl.Controls 9 { 10 /// <summary> 11 /// 扩展按钮:可设置悬浮和按下时的背景,可改变形状,并可设置按钮按下后保持锁定状态 12 /// </summary> 13 public class XButton : Button 14 { 15 #region 依赖属性 16 public static readonly DependencyProperty XMoverBrushProperty;//鼠标经过时的画刷 17 public static readonly DependencyProperty XEnterBrushProperty;//鼠标按下时的画刷 18 public static readonly DependencyProperty XUnEnabledBrushProperty;//禁用时的画刷 19 public static readonly DependencyProperty XIsFoucedBrushLockProperty;//是否得到焦点时锁住画刷 20 public static readonly DependencyProperty XShapeProperty;//外形的路径 21 public static readonly DependencyProperty XStrokeBrushProperty;//外形的路径着色 22 public static readonly DependencyProperty XStrokeThicknessProperty;//外形的路径粗细(默认为0,因为有Border边框,所以要设这个值,要先把BorderThickness设为0) 23 #endregion 24 25 #region 内部方法 26 /// <summary> 27 /// 静态构造方法 28 /// </summary> 29 static XButton() 30 { 31 //注册依赖属性 32 XButton.XMoverBrushProperty = DependencyProperty.Register("XMoverBrush", typeof(Brush), typeof(XButton), 33 new PropertyMetadata(Brushes.WhiteSmoke)); 34 XButton.XEnterBrushProperty = DependencyProperty.Register("XEnterBrush", typeof(Brush), typeof(XButton), 35 new PropertyMetadata(Brushes.Silver)); 36 XButton.XUnEnabledBrushProperty = DependencyProperty.Register("XUnEnabledBrush", typeof(Brush), typeof(XButton), 37 new PropertyMetadata(Brushes.Silver)); 38 XButton.XStrokeBrushProperty = DependencyProperty.Register("XStrokeBrush", typeof(Brush), typeof(XButton), 39 new PropertyMetadata(Brushes.Silver)); 40 XButton.XStrokeThicknessProperty = DependencyProperty.Register("XStrokeThickness", typeof(Double), typeof(XButton), 41 new PropertyMetadata(0.0)); 42 XButton.XIsFoucedBrushLockProperty = DependencyProperty.Register("XIsFoucedBrushLock", typeof(bool), typeof(XButton), 43 new PropertyMetadata(false)); 44 XButton.XShapeProperty = DependencyProperty.Register("XShape", typeof(string), typeof(XButton), 45 new PropertyMetadata("M 0 0 L 0 0 L 100 0 L 100 100 L 0 100 Z")); 46 FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(XButton), new FrameworkPropertyMetadata(typeof(XButton))); 47 } 48 #endregion 49 50 #region 公布属性 51 /// <summary> 52 /// 公布属性XMoverBrush(鼠标经过时的画刷) 53 /// </summary> 54 public Brush XMoverBrush 55 { 56 get 57 { 58 return base.GetValue(XButton.XMoverBrushProperty) as Brush; 59 } 60 set 61 { 62 base.SetValue(XButton.XMoverBrushProperty, value); 63 } 64 } 65 66 /// <summary> 67 /// 公布属性XMoverBrush(鼠标按下时的画刷) 68 /// </summary> 69 public Brush XEnterBrush 70 { 71 get 72 { 73 return base.GetValue(XButton.XEnterBrushProperty) as Brush; 74 } 75 set 76 { 77 base.SetValue(XButton.XEnterBrushProperty, value); 78 } 79 } 80 81 /// <summary> 82 /// 公布属性XUnEnabledBrush(禁用时的画刷) 83 /// </summary> 84 public Brush XUnEnabledBrush 85 { 86 get 87 { 88 return base.GetValue(XButton.XUnEnabledBrushProperty) as Brush; 89 } 90 set 91 { 92 base.SetValue(XButton.XUnEnabledBrushProperty, value); 93 } 94 } 95 96 /// <summary> 97 /// 公布属性XIsFoucedBrushLock(是否得到焦点时锁住画刷) 98 /// </summary> 99 public bool XIsFoucedBrushLock100 {101 get102 {103 return (bool)base.GetValue(XButton.XIsFoucedBrushLockProperty);104 }105 set106 {107 base.SetValue(XButton.XIsFoucedBrushLockProperty, value);108 }109 }110 111 /// <summary>112 /// 公布属性XShape(外形的路径)113 /// </summary>114 public String XShape115 {116 get117 {118 return base.GetValue(XButton.XShapeProperty) as String;119 }120 set121 {122 base.SetValue(XButton.XShapeProperty, value);123 }124 }125 126 /// <summary>127 /// 公布属性XStrokeBrush(外形的路径着色)128 /// </summary>129 public Brush XStrokeBrush130 {131 get132 {133 return base.GetValue(XButton.XStrokeBrushProperty) as Brush;134 }135 set136 {137 base.SetValue(XButton.XStrokeBrushProperty, value);138 }139 }140 141 /// <summary>142 /// 公布属性XStrokeThickness(外形的路径粗细)143 /// </summary>144 public Double XStrokeThickness145 {146 get147 {148 return (Double)base.GetValue(XButton.XStrokeThicknessProperty);149 }150 set151 {152 base.SetValue(XButton.XStrokeThicknessProperty, value);153 }154 }155 #endregion156 }157 }
看了代码上的注释应该都能明白吧!要是有不明白的可以留言。
至于源代码,我之后会整理几个控件后一起发上来的!
WPF自定义控件(一)——Button
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。