一.前言.效果图

  申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接。

还是先看看效果图吧:

  

  

  定义Button按钮名称叫FButton,主要是集成了字体图标(参考上一篇:WPF自定义控件与样式1-矢量字体图标(iconfont))。其实在WPF里,要实现本文FButton的需求,完全可以不用自定义控件,使用样式、模板就可以搞定了的。

二.按钮FButton控件定义

2.1 FButton继承自微软基础控件Button (C#代码)

  FButton继承自微软基础控件Button,没有什么逻辑代码,主要扩展了几个属性:

  • 控件外观控制的属性,如圆角、鼠标悬浮前景色背景色、是否开启动画(鼠标悬停时小图标转一圈,移开又转回去)、鼠标按下颜色等;
  • 字体图标相关属性,如字符值、字体图标大小、字体图标间距等。

详见代码:

    /// <summary>
/// FButton.xaml 的交互逻辑
/// </summary> public partial class FButton : Button
{
public static readonly DependencyProperty PressedBackgroundProperty =
DependencyProperty.Register("PressedBackground", typeof(Brush), typeof(FButton), new PropertyMetadata(Brushes.DarkBlue));
/// <summary>
/// 鼠标按下背景样式
/// </summary>
public Brush PressedBackground
{
get { return (Brush)GetValue(PressedBackgroundProperty); }
set { SetValue(PressedBackgroundProperty, value); }
} public static readonly DependencyProperty PressedForegroundProperty =
DependencyProperty.Register("PressedForeground", typeof(Brush), typeof(FButton), new PropertyMetadata(Brushes.White));
/// <summary>
/// 鼠标按下前景样式(图标、文字)
/// </summary>
public Brush PressedForeground
{
get { return (Brush)GetValue(PressedForegroundProperty); }
set { SetValue(PressedForegroundProperty, value); }
} public static readonly DependencyProperty MouseOverBackgroundProperty =
DependencyProperty.Register("MouseOverBackground", typeof(Brush), typeof(FButton), new PropertyMetadata(Brushes.RoyalBlue));
/// <summary>
/// 鼠标进入背景样式
/// </summary>
public Brush MouseOverBackground
{
get { return (Brush)GetValue(MouseOverBackgroundProperty); }
set { SetValue(MouseOverBackgroundProperty, value); }
} public static readonly DependencyProperty MouseOverForegroundProperty =
DependencyProperty.Register("MouseOverForeground", typeof(Brush), typeof(FButton), new PropertyMetadata(Brushes.White));
/// <summary>
/// 鼠标进入前景样式
/// </summary>
public Brush MouseOverForeground
{
get { return (Brush)GetValue(MouseOverForegroundProperty); }
set { SetValue(MouseOverForegroundProperty, value); }
} public static readonly DependencyProperty FIconProperty =
DependencyProperty.Register("FIcon", typeof(string), typeof(FButton), new PropertyMetadata("\ue604"));
/// <summary>
/// 按钮字体图标编码
/// </summary>
public string FIcon
{
get { return (string)GetValue(FIconProperty); }
set { SetValue(FIconProperty, value); }
} public static readonly DependencyProperty FIconSizeProperty =
DependencyProperty.Register("FIconSize", typeof(int), typeof(FButton), new PropertyMetadata());
/// <summary>
/// 按钮字体图标大小
/// </summary>
public int FIconSize
{
get { return (int)GetValue(FIconSizeProperty); }
set { SetValue(FIconSizeProperty, value); }
} public static readonly DependencyProperty FIconMarginProperty = DependencyProperty.Register(
"FIconMargin", typeof(Thickness), typeof(FButton), new PropertyMetadata(new Thickness(, , , )));
/// <summary>
/// 字体图标间距
/// </summary>
public Thickness FIconMargin
{
get { return (Thickness)GetValue(FIconMarginProperty); }
set { SetValue(FIconMarginProperty, value); }
} public static readonly DependencyProperty AllowsAnimationProperty = DependencyProperty.Register(
"AllowsAnimation", typeof(bool), typeof(FButton), new PropertyMetadata(true));
/// <summary>
/// 是否启用Ficon动画
/// </summary>
public bool AllowsAnimation
{
get { return (bool)GetValue(AllowsAnimationProperty); }
set { SetValue(AllowsAnimationProperty, value); }
} public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(FButton), new PropertyMetadata(new CornerRadius()));
/// <summary>
/// 按钮圆角大小,左上,右上,右下,左下
/// </summary>
public CornerRadius CornerRadius
{
get { return (CornerRadius)GetValue(CornerRadiusProperty); }
set { SetValue(CornerRadiusProperty, value); }
} public static readonly DependencyProperty ContentDecorationsProperty = DependencyProperty.Register(
"ContentDecorations", typeof(TextDecorationCollection), typeof(FButton), new PropertyMetadata(null));
public TextDecorationCollection ContentDecorations
{
get { return (TextDecorationCollection)GetValue(ContentDecorationsProperty); }
set { SetValue(ContentDecorationsProperty, value); }
} static FButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(FButton), new FrameworkPropertyMetadata(typeof(FButton)));
}
}

2.2 FButton控件模板定义

  模板内容分为两部分,第一部分为为基本结构,第二部分就是触发器,用触发器实现按钮不同状态的样式控制,详见代码:

    <!--FButton模板-->
<ControlTemplate x:Key="FButton_Template" TargetType="{x:Type local:FButton}">
<Border x:Name="border" Background="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path= Background}"
Height="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Height}"
CornerRadius="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=CornerRadius}"
Width="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Width}">
<!--Icon/Text-->
<StackPanel Orientation="Horizontal" VerticalAlignment="Center"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}">
<TextBlock x:Name="icon" Margin="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=FIconMargin}"
RenderTransformOrigin="0.5,0.5" Style="{StaticResource FIcon}"
Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path= FIcon}"
FontSize="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path= FIconSize}"
Foreground="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path= Foreground}">
<TextBlock.RenderTransform>
<RotateTransform x:Name="transIcon" Angle="0"/>
</TextBlock.RenderTransform>
</TextBlock> <TextBlock VerticalAlignment="Center" x:Name="txt"
TextDecorations="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=ContentDecorations}"
Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Content}"
FontSize="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=FontSize}"
Foreground="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Foreground}"></TextBlock>
</StackPanel>
</Border>
<!--触发器-->
<ControlTemplate.Triggers>
<!--设置鼠标进入时的背景、前景样式-->
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
Path=MouseOverBackground}" TargetName="border" />
<Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
Path=MouseOverForeground}" TargetName="icon"/>
<Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
Path=MouseOverForeground}" TargetName="txt"/>
</Trigger>
<!--Ficon的动画触发器-->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true"></Condition>
<Condition Property="AllowsAnimation" Value="true"></Condition>
</MultiTrigger.Conditions>
<MultiTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="transIcon" Storyboard.TargetProperty="Angle" To="180" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</MultiTrigger.EnterActions>
<MultiTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="transIcon" Storyboard.TargetProperty="Angle" To="0" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</MultiTrigger.ExitActions>
</MultiTrigger>
<!--鼠标按下时的前景、背景样式-->
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
Path=PressedBackground}" TargetName="border" />
<Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
Path=PressedForeground}" TargetName="icon"/>
<Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
Path=PressedForeground}" TargetName="txt"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" Value="0.5" TargetName="border"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

2.3 FButton基本样式

  样式定义代码:

    <!--默认样式-->
<Style TargetType="{x:Type local:FButton}">
<Setter Property="Background" Value="{StaticResource ButtonBackground}" />
<Setter Property="Foreground" Value="{StaticResource ButtonForeground}" />
<Setter Property="MouseOverBackground" Value="{StaticResource ButtonMouseOverBackground}" />
<Setter Property="MouseOverForeground" Value="{StaticResource ButtonMouseOverForeground}" />
<Setter Property="PressedBackground" Value="{StaticResource ButtonPressedBackground}" />
<Setter Property="PressedForeground" Value="{StaticResource ButtonPressedForeground}" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="Width" Value="100" />
<Setter Property="Height" Value="30" />
<Setter Property="FontSize" Value="13" />
<Setter Property="CornerRadius" Value="0" />
<Setter Property="FIconSize" Value="22" />
<Setter Property="Template" Value="{StaticResource FButton_Template}"/>
<Setter Property="Padding" Value="3,1,3,1" />
<Setter Property="Content" Value="{x:Null}" />
<Setter Property="FIconMargin" Value="0,0,5,0" />
<Setter Property="AllowsAnimation" Value="False" />
</Style>

  基本按钮的效果,参考(一.前言-效果图),示例代码:

        <StackPanel >
<core:FButton FIcon="" Margin="3">系统换转</core:FButton>
<core:FButton FIcon="" Margin="3" Width="140" Height="40" Background="#771C79" MouseOverBackground="#F20BA0" Click="FButton_Click" >WaitingBox</core:FButton>
<core:FButton FIcon="" Margin="3" Width="140" Height="40" Background="#12B512" IsDefault="True" MouseOverBackground="#08EE08" Click="FButton_Click_WindowBase">WindowBase</core:FButton> <core:FButton FIcon="" Margin="5,0,0,0" CornerRadius="16,0,0,16" AllowsAnimation="True" Click="FButton_Click_Info">Info</core:FButton>
<core:FButton FIcon="" CornerRadius="0" Click="FButton_Click_Question">Question</core:FButton>
<core:FButton FIcon="" CornerRadius="0" Click="FButton_Click_Warning">Warining</core:FButton>
<core:FButton FIcon="" CornerRadius="0,16,16,0" AllowsAnimation="True" Click="FButton_Click_Error">Error</core:FButton>
</StackPanel>

2.4 FButton透明背景样式

  背景透明效果的按钮样式

    <!--背景透明的FButton样式-->
<Style x:Key="FButton_Transparency" TargetType="{x:Type local:FButton}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="MouseOverBackground" Value="Transparent" />
<Setter Property="PressedBackground" Value="Transparent" />
<Setter Property="Foreground" Value="{StaticResource TextForeground}" />
<Setter Property="MouseOverForeground" Value="{StaticResource MouseOverForeground}" />
<Setter Property="PressedForeground" Value="{StaticResource PressedForeground}" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="Height" Value="Auto" />
<Setter Property="Width" Value="Auto" />
<Setter Property="CornerRadius" Value="0" />
<Setter Property="FontSize" Value="13" />
<Setter Property="FIconSize" Value="20" />
<Setter Property="Template" Value="{StaticResource FButton_Template}"/>
<Setter Property="Padding" Value="3,1,3,1" />
<Setter Property="Content" Value="{x:Null}" />
<Setter Property="FIconMargin" Value="0,0,2,0" />
<Setter Property="AllowsAnimation" Value="False" />
<Setter Property="Cursor" Value="Hand" />
</Style>

  示例及效果:

            <core:FButton FIcon="" Margin="5" FIconMargin="0" FIconSize="30" Style="{StaticResource FButton_Transparency}" ></core:FButton>
<core:FButton FIcon="" Margin="5" Style="{StaticResource FButton_Transparency}"></core:FButton>
<core:FButton FIcon="" Margin="5" Style="{StaticResource FButton_Transparency}" IsEnabled="False"></core:FButton> <core:FButton FIcon="" Margin="3" Style="{StaticResource FButton_Transparency}">如何开启调试模式?</core:FButton>
<core:FButton FIcon="" Margin="3" Style="{StaticResource FButton_Transparency}" IsEnabled="False">设备检测</core:FButton>
<core:FButton FIcon="" Margin="3" Style="{StaticResource FButton_Transparency}">爸爸回来了</core:FButton>

  

2.3 类似LinkButton(超链接)样式

样式定义:

    <!--LinkButton的FButton样式,默认无FIcon-->
<Style x:Key="FButton_LinkButton" TargetType="{x:Type local:FButton}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="MouseOverBackground" Value="Transparent" />
<Setter Property="PressedBackground" Value="Transparent" />
<Setter Property="Foreground" Value="{StaticResource LinkForeground}" />
<Setter Property="MouseOverForeground" Value="{StaticResource MouseOverForeground}" />
<Setter Property="PressedForeground" Value="{StaticResource PressedForeground}" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="Height" Value="Auto" />
<Setter Property="Width" Value="Auto" />
<Setter Property="CornerRadius" Value="0" />
<Setter Property="FontSize" Value="13" />
<Setter Property="FIconSize" Value="20" />
<Setter Property="Template" Value="{StaticResource FButton_Template}"/>
<Setter Property="Padding" Value="3,1,3,1" />
<Setter Property="Content" Value="{x:Null}" />
<Setter Property="FIconMargin" Value="0" />
<Setter Property="FIcon" Value="" />
<Setter Property="AllowsAnimation" Value="False" />
<Setter Property="ContentDecorations" Value="Underline" />
<Setter Property="Cursor" Value="Hand" />
</Style>

示例及效果:

            <core:FButton Margin="3,15" Style="{StaticResource FButton_LinkButton}" >如何开启调试模式?</core:FButton>
<core:FButton FIcon="" Margin="3" Style="{StaticResource FButton_LinkButton}">设备检测</core:FButton>
<core:FButton Margin="3" Style="{StaticResource FButton_LinkButton}">爸爸回来了</core:FButton>

  

附录:参考引用

WPF自定义控件与样式(1)-矢量字体图标(iconfont)

WPF自定义控件与样式(2)-自定义按钮FButton

WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展

WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式

WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展

WPF自定义控件与样式(6)-ScrollViewer与ListBox自定义样式

WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式

WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox

WPF自定义控件与样式(9)-树控件TreeView与菜单Menu-ContextMenu

WPF自定义控件与样式(10)-进度控件ProcessBar自定义样

WPF自定义控件与样式(11)-等待/忙/正在加载状态-控件实现

WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表

WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBox

WPF自定义控件与样式(14)-轻量MVVM模式实践

WPF自定义控件与样式(15)-终结篇

版权所有,文章来源:http://www.cnblogs.com/anding

个人能力有限,本文内容仅供学习、探讨,欢迎指正、交流。

WPF自定义控件与样式(2)-自定义按钮FButton的更多相关文章

  1. 【转】WPF自定义控件与样式(2)-自定义按钮FButton

    一.前言.效果图 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等 还是先看看效果图吧:   定义Button按钮名称叫FButton,主要是集成了 ...

  2. WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBox

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 自定义 ...

  3. 【转】WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBox

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要内容: 自定义Window窗体样式: 基于自定义窗体实现自定义MessageB ...

  4. WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Che ...

  5. WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 日历控 ...

  6. WPF自定义控件与样式(6)-ScrollViewer与ListBox自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Scr ...

  7. WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Dat ...

  8. WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 下拉选 ...

  9. WPF自定义控件与样式(10)-进度控件ProcessBar自定义样

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Pro ...

随机推荐

  1. Java数据结构——栈的应用(以数制转换为例子)

    看一万遍,不如自己动手实践,请不要直接copy代码,先自己去理解例子实现的原理,然后试着自己动手去实践. 用Java去实现栈操作,会用到stack这个类,这类中有几个方法需要知道他们的用法  bool ...

  2. hdu1532网络流

    (双倍经验题) 第二次写dinic模板,居然一遍写对了,而且短了不少O(∩_∩)O~ #include <cstdio> #define INF 2147483647 int n,m,an ...

  3. 闭包和重写函数 返回IE浏览器版本号

    开发过程中我们有时候需要知道IE的版本号,我们知道得到IE的版本号的方法: var v = 3, div = document.createElement('div'), all = div.getE ...

  4. Junit测试框架 Tips

    关于Junit测试框架使用的几点总结: 1.Junit中的测试注解: @Test →每个测试方法前都需要添加该注解,这样才能使你的测试方法交给Junit去执行. @Before →在每个测试方法执行前 ...

  5. Ubuntu 14.04 更换阿里云源

    sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak #备份 sudo vim /etc/apt/sources.list #修改 sudo ...

  6. JAVA多线程售票问题

    //定义一个类实现Runnable接口,定义一个需要同步的售票方法,然后重写run方法调用售票的sale方法 class SaleTicket implements Runnable{ private ...

  7. Qt下的udp编程

    项目需要一个基于udp的客户端, 看着Qt是有个QUdpSocket的类的, 但自带的例子和类的说明都没咋说明白: 怎么用一个QUdpSocket既当发送端, 又当接收端? 谷歌一顿后, 发现很多老内 ...

  8. VS2015 调试时 编辑并继续不可用

    最近在项目中遇到一次调试时 编辑并继续不可用.结合网上说的工具->设置->调试->常规下的一些操作,到后来还是不可用,最后把项目的解决方案平台改成Mixed Platform ,之后 ...

  9. easyui-conbotree树形下拉框。。。转

    最近一直在研究这个树形的下拉选择框,感觉非常的有用,现在整理下来供大家使用: 首先数据库的表架构设计和三级菜单联动的表结构是一样,(父子关系) 1.下面我们用hibernate建一下对应的额实体类: ...

  10. xxxxxxxx

    class IndexHandler(BaseRequestHandler): def get(self, page=1): print('iiiiiiiiiiiiiiiii') current_ti ...