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 XIsFoucedBrushLock
100         {
101             get
102             {
103                 return (bool)base.GetValue(XButton.XIsFoucedBrushLockProperty);
104             }
105             set
106             {
107                 base.SetValue(XButton.XIsFoucedBrushLockProperty, value);
108             }
109         }
110 
111         /// <summary>
112         /// 公布屬性XShape(外形的路徑)
113         /// </summary>
114         public String XShape
115         {
116             get
117             {
118                 return base.GetValue(XButton.XShapeProperty) as String;
119             }
120             set
121             {
122                 base.SetValue(XButton.XShapeProperty, value);
123             }
124         }
125         
126         /// <summary>
127         /// 公布屬性XStrokeBrush(外形的路徑着色)
128         /// </summary>
129         public Brush XStrokeBrush
130         {
131             get
132             {
133                 return base.GetValue(XButton.XStrokeBrushProperty) as Brush;
134             }
135             set
136             {
137                 base.SetValue(XButton.XStrokeBrushProperty, value);
138             }
139         }
140 
141         /// <summary>
142         /// 公布屬性XStrokeThickness(外形的路徑粗細)
143         /// </summary>
144         public Double XStrokeThickness
145         {
146             get
147             {
148                 return (Double)base.GetValue(XButton.XStrokeThicknessProperty);
149             }
150             set
151             {
152                 base.SetValue(XButton.XStrokeThicknessProperty, value);
153             }
154         }
155         #endregion
156     }
157 }

  看了代碼上的注釋應該都能明白吧!要是有不明白的可以留言。

  至於源代碼,我之后會整理幾個控件后一起發上來的!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM