WPF自定义控件和样式之自定义按钮(Button)

作者:小明GG 时间:2022-04-09 14:39:32 

一、前言

程序界面上的按钮多种多样,常用的就这几种:普通按钮、图标按钮、文字按钮、图片文字混合按钮。本文章记录了不同样式类型的按钮实现方法。下面话不多说了,来一起看看详细的介绍吧。

二、固定样式的按钮

固定样式的按钮一般在临时使用时或程序的样式比较固定时才会使用,按钮整体样式不需要做大的改动。

2.1 普通按钮-扁平化风格

先看效果:

WPF自定义控件和样式之自定义按钮(Button)

定义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>

上述代码实现了Button按钮的扁平化样式,如果你想调整颜色风格,通过修改Background的值可实现默认颜色,鼠标经过颜色以及鼠标按下颜色。

2.2 图标按钮

先看效果:

WPF自定义控件和样式之自定义按钮(Button)

Button样式的代码和扁平化Button差不多,只是把TextBlock控件替换成了Image控件,另外需要设置Button默认的背景色为透明。废话不多说看代码:


<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需要自己准备图片资源,IsMouseOver和IsPressed的图片资源可自己替换,替换之后能有更丰富的效果呈现。

2.3 图标文字混合按钮

效果:

WPF自定义控件和样式之自定义按钮(Button)

实现代码:


<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中的图标文字按钮样式差不多,只需要把Image控件去掉就行。

三、复用性高的按钮

要想实现复用性高的按钮,就必须新建自定义控件。下面这个实例通过自定义控件实现上述所有效果,并且可以随意更改风格。

首先在项目中右键-添加-新建项-自定义控件。

WPF自定义控件和样式之自定义按钮(Button)

新建自定义控件之后,添加依赖属性。代码如下:


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
}

为不同类型按钮设置样式,代码如下:


<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>

效果如下:

WPF自定义控件和样式之自定义按钮(Button)

至此已经完成Button控件的扩展功能,如果想要添加动画或者设置图标的位置和边距等,可以自己另外添加依赖属性来扩展。

来源:http://www.cnblogs.com/xiaomingg/p/8699125.html

标签:wpf,自定义,button
0
投稿

猜你喜欢

  • java guava主要功能介绍及使用心得总结

    2023-07-30 11:01:54
  • Java内存模型JMM详解

    2023-11-28 13:08:50
  • 举例讲解设计模式中的访问者模式在Java编程中的运用

    2022-04-04 08:00:45
  • Spring自动装配Bean实现过程详解

    2023-10-31 18:35:21
  • Android中获得正在运行的程序和系统服务的方法

    2023-01-19 21:05:42
  • Android实现webview实例代码

    2022-05-28 13:32:32
  • C#实现单例模式的6种方法小结

    2023-09-13 21:02:57
  • Android本地数据存储Room实践和优化技巧

    2023-11-04 09:01:30
  • java迭代器原理及迭代map的四种方式

    2021-08-27 12:04:30
  • idea激活ActivateJrebel热部署的方法详解

    2023-04-05 17:54:42
  • Android实现密码明密文切换(小眼睛)

    2023-07-01 15:42:18
  • 解决C#全屏幕截图的实现方法

    2023-10-25 00:41:15
  • 详解Java面向对象编程之多态

    2023-08-28 19:17:06
  • 解决jasperreport导出的pdf每页显示的记录太少问题

    2023-04-14 13:02:01
  • 快速理解Java垃圾回收和jvm中的stw

    2021-09-06 20:27:17
  • JAVA垃圾收集器与内存分配策略详解

    2023-05-20 16:33:20
  • SpringBoot Test类注入失败的解决

    2023-05-20 13:59:40
  • Flutter持久化存储之数据库存储(sqflite)详解

    2022-11-16 04:34:30
  • Java 六类运算符详解

    2023-08-27 20:37:37
  • C#创建、部署、调用WebService图文实例详解

    2022-05-03 06:35:20
  • asp之家 软件编程 m.aspxhome.com