服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - WPF自定义控件和样式之自定义按钮(Button)

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

2022-02-23 13:26小明GG C#

接触WPF也有两个多月了,有了一定的理论基础和项目经验,现在打算写一个系列,做出来一个WPF的控件库。下面这篇文章主要给大家介绍了关于WPF自定义控件和样式之自定义按钮(Button)的相关资料,需要的朋友可以参考下。

一、前言

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

二、固定样式的按钮

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

2.1 普通按钮-扁平化风格

先看效果:

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

定义button的样式,详见代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<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>

引用方法:

?
1
2
3
4
<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默认的背景色为透明。废话不多说看代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<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)

实现代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<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)

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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
 }

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
<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>

然后就可以引用该控件了:

?
1
2
3
4
5
6
7
8
<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

延伸 · 阅读

精彩推荐
  • C#VS2012 程序打包部署图文详解

    VS2012 程序打包部署图文详解

    VS2012虽然没有集成打包工具,但它为我们提供了下载的端口,需要我们手动安装一个插件InstallShield。网上有很多第三方的打包工具,但为什么偏要使用微软...

    张信秀7712021-12-15
  • C#C#微信公众号与订阅号接口开发示例代码

    C#微信公众号与订阅号接口开发示例代码

    这篇文章主要介绍了C#微信公众号与订阅号接口开发示例代码,结合实例形式简单分析了C#针对微信接口的调用与处理技巧,需要的朋友可以参考下...

    smartsmile20127762021-11-25
  • C#C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    这篇文章主要介绍了C#设计模式之Strategy策略模式解决007大破密码危机问题,简单描述了策略模式的定义并结合加密解密算法实例分析了C#策略模式的具体使用...

    GhostRider10972022-01-21
  • C#三十分钟快速掌握C# 6.0知识点

    三十分钟快速掌握C# 6.0知识点

    这篇文章主要介绍了C# 6.0的相关知识点,文中介绍的非常详细,通过这篇文字可以让大家在三十分钟内快速的掌握C# 6.0,需要的朋友可以参考借鉴,下面来...

    雨夜潇湘8272021-12-28
  • C#利用C#实现网络爬虫

    利用C#实现网络爬虫

    这篇文章主要介绍了利用C#实现网络爬虫,完整的介绍了C#实现网络爬虫详细过程,感兴趣的小伙伴们可以参考一下...

    C#教程网11852021-11-16
  • C#SQLite在C#中的安装与操作技巧

    SQLite在C#中的安装与操作技巧

    SQLite,是一款轻型的数据库,用于本地的数据储存。其优点有很多,下面通过本文给大家介绍SQLite在C#中的安装与操作技巧,感兴趣的的朋友参考下吧...

    蓝曈魅11162022-01-20
  • C#深入理解C#的数组

    深入理解C#的数组

    本篇文章主要介绍了C#的数组,数组是一种数据结构,详细的介绍了数组的声明和访问等,有兴趣的可以了解一下。...

    佳园9492021-12-10
  • C#如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    这篇文章主要给大家介绍了关于如何使用C#将Tensorflow训练的.pb文件用在生产环境的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴...

    bbird201811792022-03-05