WPF自定義控件和樣式之自定義按鈕(Button)
一、前言
程序界面上的按鈕多種多樣,常用的就這幾種:普通按鈕、圖標(biāo)按鈕、文字按鈕、圖片文字混合按鈕。本文章記錄了不同樣式類型的按鈕實現(xiàn)方法。下面話不多說了,來一起看看詳細(xì)的介紹吧。
二、固定樣式的按鈕
固定樣式的按鈕一般在臨時使用時或程序的樣式比較固定時才會使用,按鈕整體樣式不需要做大的改動。
2.1 普通按鈕-扁平化風(fēng)格
先看效果:

定義Button的樣式,詳見代碼:
<Style x:Key="BtnInfoStyle" TargetType="Button">
<Setter Property="Width" Value="70"/>
<Setter Property="Height" Value="25"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="#43a9c7"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True">
<TextBlock Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="Background" Value="#2f96b4"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="border" Property="Background" Value="#2a89a4"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
引用方法:
<Grid Background="White">
<StackPanel Orientation="Horizontal" Margin="10" VerticalAlignment="Top">
<Button Style="{StaticResource BtnInfoStyle}" Content="信息" Margin="5 0"/>
</Grid>
上述代碼實現(xiàn)了Button按鈕的扁平化樣式,如果你想調(diào)整顏色風(fēng)格,通過修改Background的值可實現(xiàn)默認(rèn)顏色,鼠標(biāo)經(jīng)過顏色以及鼠標(biāo)按下顏色。
2.2 圖標(biāo)按鈕
先看效果:

Button樣式的代碼和扁平化Button差不多,只是把TextBlock控件替換成了Image控件,另外需要設(shè)置Button默認(rèn)的背景色為透明。廢話不多說看代碼:
<Style x:Key="BtnImageStyle1" TargetType="Button">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<Image x:Name="Img" VerticalAlignment="Center" HorizontalAlignment="Center" Source="/Images/button1.png" Stretch="None"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Img" Property="Source" Value="/Images/button1.png"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Img" Property="Source" Value="/Images/button1.png"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
這里的button1.png需要自己準(zhǔn)備圖片資源,IsMouseOver和IsPressed的圖片資源可自己替換,替換之后能有更豐富的效果呈現(xiàn)。
2.3 圖標(biāo)文字混合按鈕
效果:

實現(xiàn)代碼:
<Style x:Key="BtnImgTxtStyle1" TargetType="Button">
<Setter Property="Foreground" Value="#555"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Image Source="Images/adshut.png" Stretch="None"/>
<TextBlock x:Name="Txt" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="#333333" TargetName="Txt"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
2.4 文字按鈕和2.3中的圖標(biāo)文字按鈕樣式差不多,只需要把Image控件去掉就行。
三、復(fù)用性高的按鈕
要想實現(xiàn)復(fù)用性高的按鈕,就必須新建自定義控件。下面這個實例通過自定義控件實現(xiàn)上述所有效果,并且可以隨意更改風(fēng)格。
首先在項目中右鍵-添加-新建項-自定義控件。

新建自定義控件之后,添加依賴屬性。代碼如下:
public class ButtonEx : Button
{
static ButtonEx()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ButtonEx), new FrameworkPropertyMetadata(typeof(ButtonEx)));
}
public ButtonType ButtonType
{
get { return (ButtonType)GetValue(ButtonTypeProperty); }
set { SetValue(ButtonTypeProperty, value); }
}
public static readonly DependencyProperty ButtonTypeProperty =
DependencyProperty.Register("ButtonType", typeof(ButtonType), typeof(ButtonEx), new PropertyMetadata(ButtonType.Normal));
public ImageSource Icon
{
get { return (ImageSource)GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
}
public static readonly DependencyProperty IconProperty =
DependencyProperty.Register("Icon", typeof(ImageSource), typeof(ButtonEx), new PropertyMetadata(null));
public CornerRadius CornerRadius
{
get { return (CornerRadius)GetValue(CornerRadiusProperty); }
set { SetValue(CornerRadiusProperty, value); }
}
public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(ButtonEx), new PropertyMetadata(new CornerRadius(0)));
public Brush MouseOverForeground
{
get { return (Brush)GetValue(MouseOverForegroundProperty); }
set { SetValue(MouseOverForegroundProperty, value); }
}
public static readonly DependencyProperty MouseOverForegroundProperty =
DependencyProperty.Register("MouseOverForeground", typeof(Brush), typeof(ButtonEx), new PropertyMetadata());
public Brush MousePressedForeground
{
get { return (Brush)GetValue(MousePressedForegroundProperty); }
set { SetValue(MousePressedForegroundProperty, value); }
}
public static readonly DependencyProperty MousePressedForegroundProperty =
DependencyProperty.Register("MousePressedForeground", typeof(Brush), typeof(ButtonEx), new PropertyMetadata());
public Brush MouseOverBorderbrush
{
get { return (Brush)GetValue(MouseOverBorderbrushProperty); }
set { SetValue(MouseOverBorderbrushProperty, value); }
}
public static readonly DependencyProperty MouseOverBorderbrushProperty =
DependencyProperty.Register("MouseOverBorderbrush", typeof(Brush), typeof(ButtonEx), new PropertyMetadata());
public Brush MouseOverBackground
{
get { return (Brush)GetValue(MouseOverBackgroundProperty); }
set { SetValue(MouseOverBackgroundProperty, value); }
}
public static readonly DependencyProperty MouseOverBackgroundProperty =
DependencyProperty.Register("MouseOverBackground", typeof(Brush), typeof(ButtonEx), new PropertyMetadata());
public Brush MousePressedBackground
{
get { return (Brush)GetValue(MousePressedBackgroundProperty); }
set { SetValue(MousePressedBackgroundProperty, value); }
}
public static readonly DependencyProperty MousePressedBackgroundProperty =
DependencyProperty.Register("MousePressedBackground", typeof(Brush), typeof(ButtonEx), new PropertyMetadata());
}
public enum ButtonType
{
Normal,
Icon,
Text,
IconText
}
為不同類型按鈕設(shè)置樣式,代碼如下:
<Style TargetType="{x:Type local:ButtonEx}">
<Style.Triggers>
<Trigger Property="ButtonType" Value="Normal">
<Setter Property="Background" Value="#43a9c7"/>
<Setter Property="MouseOverBackground" Value="#2f96b4"/>
<Setter Property="MousePressedBackground" Value="#2a89a4"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="MouseOverForeground" Value="White"/>
<Setter Property="MousePressedForeground" Value="White"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ButtonEx}">
<Border x:Name="border" Background="{TemplateBinding Background}" CornerRadius="{TemplateBinding CornerRadius}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" SnapsToDevicePixels="True">
<TextBlock x:Name="txt" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="Background" Value="{Binding MouseOverBackground,RelativeSource={RelativeSource TemplatedParent}}"/>
<Setter TargetName="txt" Property="Foreground" Value="{Binding MouseOverForeground,RelativeSource={RelativeSource TemplatedParent}}"/>
<Setter TargetName="border" Property="BorderBrush" Value="{Binding MouseOverBorderbrush,RelativeSource={RelativeSource TemplatedParent}}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="border" Property="Background" Value="{Binding MousePressedBackground,RelativeSource={RelativeSource TemplatedParent}}"/>
<Setter TargetName="txt" Property="Foreground" Value="{Binding MousePressedForeground,RelativeSource={RelativeSource TemplatedParent}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="ButtonType" Value="Icon">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ButtonEx}">
<Border Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<Image x:Name="Img" VerticalAlignment="Center" HorizontalAlignment="Center" Source="{TemplateBinding Icon}" Stretch="None"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.8"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" Value="0.9"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="ButtonType" Value="Text">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Foreground" Value="#002c99"/>
<Setter Property="MouseOverForeground" Value="#FF2c99"/>
<Setter Property="MousePressedForeground" Value="#002c99"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ButtonEx}">
<TextBlock x:Name="txt" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{Binding MouseOverForeground,RelativeSource={RelativeSource TemplatedParent}}" TargetName="txt"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Foreground" Value="{Binding MousePressedForeground,RelativeSource={RelativeSource TemplatedParent}}" TargetName="txt"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="ButtonType" Value="IconText">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Foreground" Value="#555"/>
<Setter Property="MouseOverForeground" Value="#555"/>
<Setter Property="MousePressedForeground" Value="#555"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ButtonEx}">
<Border>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Image Source="{TemplateBinding Icon}" Stretch="None"/>
<TextBlock x:Name="Txt" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{Binding MouseOverForeground,RelativeSource={RelativeSource TemplatedParent}}" TargetName="Txt"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Foreground" Value="{Binding MousePressedForeground,RelativeSource={RelativeSource TemplatedParent}}" TargetName="Txt"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
然后就可以引用該控件了:
<Grid> <WrapPanel> <local:ButtonEx Content="信息" Width="75" Height="25" Margin="10" ButtonType="Normal"/> <local:ButtonEx Icon="/Images/button1.png" Margin="10" ButtonType="Icon"/> <local:ButtonEx Content="文字按鈕" Margin="10" ButtonType="Text"/> <local:ButtonEx Content="圖文按鈕" Icon="/Images/adshut.png" Margin="10" ButtonType="IconText"/> </WrapPanel> </Grid>
效果如下:

至此已經(jīng)完成Button控件的擴(kuò)展功能,如果想要添加動畫或者設(shè)置圖標(biāo)的位置和邊距等,可以自己另外添加依賴屬性來擴(kuò)展。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
C# 使用 Castle 實現(xiàn) AOP及如何用 Autofac 集成 Castle
這篇文章主要介紹了C# 使用 Castle 實現(xiàn) AOP及如何用 Autofac 集成 Castle,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下2021-02-02

