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

一、前言

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

二、固定样式的按钮

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

2.1 普通按钮-扁平化风格

先看效果:

定义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 图标按钮

先看效果:

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 图标文字混合按钮

效果:

实现代码:

<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控件去掉就行。

三、复用性高的按钮

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

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

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

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>

效果如下:

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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • WPF实现窗体中的悬浮按钮

    WPF实现窗体中的悬浮按钮,按钮可拖动,吸附停靠在窗体边缘. 控件XAML代码: <Button x:Class="SunCreate.Common.Controls.FloatButton" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmln

  • WPF水珠效果按钮组的实现教程

    效果图 相关知识 这部分基本就是废话,网上都能找到,我只不过是整理了以下.建议先不看,用到的时候可以回来看看 贝塞尔曲线 先来看两组图,有助于理解什么是贝塞尔曲线(图片取自维基百科,参考链接1) 二次贝塞尔曲线: P0是起点,P2是终点,P1是控制点 三次贝塞尔曲线: P0是起点,P2是终点,P1是控制点1,P2是控制点2 依次连接所有点,组成线段 t是比例,在0-1之间,就是每条线段的长度都是1 贝塞尔曲线就是最里层的线段在t位置的点所组成的路径 三次贝塞尔曲线公式:B(t)=(1-t)^3*

  • WPF制作带小箭头的按钮完整代码

    什么是WPF WPF(Windows Presentation Foundation)是微软推出的基于Windows 的用户界面框架,属于.NET Framework 3.0的一部分.它提供了统一的编程模型.语言和框架,真正做到了分离界面设计人员与开发人员的工作:同时它提供了全新的多媒体交互用户图形界面. 在没给大家介绍实现代码之前,先给大家看下效果图,如果大家感觉效果不错,请参考实现代码: XAML代码: <ControlTemplate x:Key="btnTpl" Targ

  • WPF图片按钮的实现方法

    本文实例为大家分享了WPF图片按钮的实现代码,供大家参考,具体内容如下 直接代码 public class ImageButton : System.Windows.Controls.Button { /// <summary> /// 图片 /// </summary> public static readonly DependencyProperty ImageProperty = DependencyProperty.Register("Image", t

  • WPF微信聊天和通讯录按钮样式代码分享

    一.先用Path画一下轮廓 <Path Stroke="Red" StrokeThickness="1" Margin="10" StrokeDashCap="Round"> <Path.Data> <GeometryGroup> <PathGeometry Figures="M 4,40 A 16,13 0 1 1 10,45 L 3,48 Z" /> &l

  • WPF MVVM制作发送短信小按钮

    最近做一个项目,因为涉及到注册,因此需要发送短信,一般发送短信都有一个倒计时的小按钮,因此,就做了一个,在此做个记录. 一.发送消息 没有调用公司的短信平台,只是模拟前台生成一串数字,将此串数字输出一下. 在这个部分写了两个类文件:一个是生成随机数,一个是模拟发送此数字的. 1.因为生成几位随机数,是必须要到项目上线之前才能定的,因此,写了一个带参数的函数,如下 /// <summary> /// 生成随机验证码 /// </summary> public static class

  • WPF中button按钮同时点击多次触发click解决方法

    解决WPF中button按钮同时点击多次触发click的方法,供大家参考,具体内容如下 DateTime lastClick = DateTime.Now; object obj = new object(); int i = 0; private void Button_Click(object sender, RoutedEventArgs e) { this.IsEnabled = false; var t = (DateTime.Now - lastClick).TotalMillise

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

    一.前言 程序界面上的按钮多种多样,常用的就这几种:普通按钮.图标按钮.文字按钮.图片文字混合按钮.本文章记录了不同样式类型的按钮实现方法.下面话不多说了,来一起看看详细的介绍吧. 二.固定样式的按钮 固定样式的按钮一般在临时使用时或程序的样式比较固定时才会使用,按钮整体样式不需要做大的改动. 2.1 普通按钮-扁平化风格 先看效果: 定义Button的样式,详见代码: <Style x:Key="BtnInfoStyle" TargetType="Button&quo

  • C#中Winform 实现Ajax效果自定义按钮

    技术看点 WinForm自定义控件的使用 自定义控件gif动画的播放 需求及效果 又来一波 C# GDI自定义控件show .这个控件已经使用几年了,最近找出来重构一下.原来是没有边框的,那么导致导航的功能不是很突出.本来想加个效果:在执行单击时显示Loading动画,在执行完单击事件后恢复原样.这就是网页里见到的局部刷新,Ajax常用的场景.需求来自几年前一个智能储物柜项目,人机界面有个美工设计好的效果图,为了省事和通用,需要一个透明的按钮来实现导航的任务.就是控件只是设计时可见,运行时不可见

  • C# WPF 自定义按钮的方法

    本文介绍WPF一种自定义按钮的方法. 实现效果 使用图片做按钮背景: 自定义鼠标进入时效果: 自定义按压效果: 自定义禁用效果 实现效果如下图所示: 实现步骤 创建CustomButton.cs,继承自Button: 创建一个资源文件ButtonStyles.xaml: 在资源文件中设计按钮的Style: 在CustomButton.cs中添加Style中需要的依赖属性: 在程序中添加资源并引用(为了方便在不同的程序中引用自定义按钮,自定义按钮放在独立的类库中,应用程序中进行资源合并即可). 示

  • IOS 开发之自定义按钮实现文字图片位置随意定制

    IOS 开发之自定义按钮实现文字图片位置随意定制 可能有些看到这篇文章的朋友会觉得很不屑:"按钮谁不会自定义?还需要看你的?" 也确实,按钮是我们项目中最常见的控件之一,天天在使用.对于不同类型的按钮,我们是否有更加简便的方法来实现需求是我们需要做的.这里我提出自己的两种方法,您可以对你自己平时自定义按钮的方法做一下对比,看看哪种方法更加简单. 多说一句,千万不要觉得知识简单,觉得自己会了,没必要学习.'往往简单的东西存在大智慧'(这个比给满分),知识都是慢慢积累出来的. 按钮是应用中

  • Jquery Mobile 自定义按钮图标

    很多朋友都反应jquery mobile自带的图标真的是少之又少,另外我也觉得图标偏小(系统自带的是18*18的),于是琢磨着如何自定义按钮图标,下面小编把我的方法分享给大家. 刚接触Jquery Mobile框架,遇到个很现实问题,就是如何自定义按钮图标,我觉得jquery mobile 自带的图标实在是太少了,另外我觉得图标也偏小(系统自带的应该是18*18的)下面是我的方法,希望大家踊跃拍砖. 1.第一种方法是比较简单的,但是有前提,前提就是你自定义的图标大小应该和系统内置的保持一致,这样

  • vue-video-player 通过自定义按钮组件实现全屏切换效果【推荐】

    最近公司的产品上线,一些高级功能在基础版本中不对用户开发,通过视频的形式展示. 产品开发用的是 vue, 经同事介绍使用了vue-video-player视频播放插件,通过 demo案例很快实现了视频播放效果 <video-player class="vjs-custom-skin" ref="videoPlayer1" :options="playerOptions" :playsinline="true" :even

  • c# WPF中CheckBox样式的使用总结

    背景 很多时候我们使用WPF开发界面的时候经常会用到各种空间,很多时候我们需要去自定义控件的样式来替换默认的样式,今天通过两个方法来替换WPF中的CheckBox样式,透过这两个例子我们可以掌握基本的WPF样式的开发如何定义ControlTemplate以及使用附加属性来为我们的控件增加新的样式. 常规使用 我们在使用CheckBox的时候,原始的样式有时不能满足我们的需求,这是我们就需要更改其模板,比如我们常用的一种,在播放器中"播放"."暂停"按钮,其实这也是一

  • Android 自定义按钮点击事件和长按事件对比

     Android 自定义按钮点击事件和长按事件对比 一个按钮同时实现点击和长按事件,有时候会有冲突,我们针对这一现象来自定义按钮来区分点击和长按事件 1.xml中 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="mat

  • vue 使用element-ui中的Notification自定义按钮并实现关闭功能及如何处理多个通知

    vue 使用element-ui中的Notification自定义按钮并实现关闭功能及如何处理多个通知 使用element-ui中的Notification,只有一个message属性是有很大的操作空间,其余的都是写死的,无法进行扩展,达不到想要的效果.所以只能在message上下功夫. 在element-ui官方文档中可以看到Notification中的message属性是可以处理VNode的所以我们可以使用VNode来达到我们需要的效果. 如何关闭通知呢? 当创建通知的时候,会返回该通知的实

  • 微信小程序分享功能之按钮button 边框隐藏和点击隐藏

    先上图 样式设置: 在小程序社区看了下,说是伪类造成的.于是就重新定义下样式.然后就 ok 了. 总结 以上所述是小编给大家介绍的微信小程序分享功能之按钮button 边框隐藏和点击隐藏,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的.在此也非常感谢大家对我们网站的支持!

随机推荐