首页 > 代码库 > 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