我们知道WPF中普通的按钮,长得丑,所以自定义按钮,在所难免。我们给按钮添加 MoveBrush,EnterBrush两把刷子,其实就是鼠标经过和鼠标按下的效果。只不过这不是普通的刷子,而是带图片的ImageBrush刷子。
1 public class ShareButton : Button 2 { 3 /// <summary> 4 /// 鼠标移走 5 /// </summary> 6 public static readonly DependencyProperty MoveBrushProperty; 7 public Brush MoveBrush 8 { 9 set 10 { 11 base.SetValue(ShareButton.MoveBrushProperty, value); 12 } 13 get 14 { 15 return base.GetValue(ShareButton.MoveBrushProperty) as Brush; 16 } 17 } 18 public static readonly DependencyProperty EnterBrushProperty; 19 /// <summary> 20 /// 鼠标进入 21 /// </summary> 22 public Brush EnterBrush 23 { 24 set 25 { 26 base.SetValue(ShareButton.EnterBrushProperty, value); 27 } 28 get 29 { 30 return base.GetValue(ShareButton.EnterBrushProperty) as Brush; 31 } 32 } 33 static ShareButton() 34 { 35 //注册属性 36 ShareButton.MoveBrushProperty = DependencyProperty.Register("MoveBrush", typeof(Brush), typeof(ShareButton), new PropertyMetadata(null)); 37 ShareButton.EnterBrushProperty = DependencyProperty.Register("EnterBrush", typeof(Brush), typeof(ShareButton), new PropertyMetadata(null)); 38 FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(ShareButton), new FrameworkPropertyMetadata(typeof(ShareButton))); 39 } 40 public ShareButton() 41 { 42 base.Content = ""; 43 } 44 }
从代码中可以看出,DependencyProperty MoveBrushProperty是个依赖属性,MoveBrush提供了对MoveBrushProperty属性的封装。那问题来了,什么是依赖属性?
传统中.net framework中的属性,也被称为CLR属性,它在实例化的时候会分配数据存储空间。而包含依赖属性的对象被称为依赖对象,它在实例化的时候并不会直接分配数据存储空间,而是保留了这样的分配能力。如果说,我们直接给这个依赖属性赋值的话,它才开始分配空间,如果它依赖于其它对象的话,也就是说,这个依赖属性的值是从其它对象那儿”拿来”的话,就不用分配内存了,而是需要绑定。
我查看了下Button的类层次结构:
Button: ButtonBase:ContentControl,因此我们自定义的 ShareButton继承自Button,自然是依赖对象,所以理所当然地可以自定义依赖属性了。
再来看看这个控件如何使用?
1、添加命名空间: xmlns:s="clr-namespace:ShareControl;assembly=ShareControl"
2、这是一个登陆按钮
1 <s:ShareButton x:Name="btnLogin" Click="btnLogin_Click" FontSize="14" Content="登 录" Width="235" Height="33" Foreground="White" Cursor="Hand" IsDefault="True"> 2 3 <s:ShareButton.EnterBrush> 4 <ImageBrush ImageSource="Skin/Icon/login_button.png"/> 5 </s:ShareButton.EnterBrush> 6 <s:ShareButton.MoveBrush> 7 <ImageBrush ImageSource="Skin/Icon/login_button_hover.png"/> 8 </s:ShareButton.MoveBrush> 9 <s:ShareButton.Background> 10 <ImageBrush ImageSource="Skin/Icon/login_button.png"/> 11 </s:ShareButton.Background> 12 </s:ShareButton>
运行效果:
鼠标经过时,是另外一个背景
自定义按钮长得这么漂亮,肯定需要样式的支持:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:ShareControl"> <Style x:Key="{x:Type local:ShareButton }" TargetType="{x:Type local:ShareButton}"> <Setter Property="FocusVisualStyle" Value="{x:Null}"/> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:ShareButton}"> <Border Name="border" BorderBrush="{TemplateBinding Control.BorderBrush}" BorderThickness="{TemplateBinding Control.BorderThickness}" SnapsToDevicePixels="True" Width="{TemplateBinding FrameworkElement.Width}" Height="{TemplateBinding FrameworkElement.Height}" Background="{TemplateBinding Control.Background}"> <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" /> </Border> <ControlTemplate.Triggers> <Trigger Property="UIElement.IsMouseOver" Value="True"> <Setter TargetName="border" Value="{Binding MoveBrush, RelativeSource={RelativeSource TemplatedParent}}" Property="Border.Background" /> </Trigger> <Trigger Property="ButtonBase.IsPressed" Value="True"> <Setter TargetName="border" Value="{Binding EnterBrush, RelativeSource={RelativeSource TemplatedParent}}" Property="Border.Background" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>