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

一.前言.效果图

  还是先看看效果图吧:

  

  

  定义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(20));
        /// <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(0, 1, 3, 1)));
        /// <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(2)));
        /// <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 >
            <xly:FButton FIcon="" Margin="3">系统换转</xly:FButton>
            <xly:FButton FIcon="" Margin="3" Width="140" Height="40" Background="#771C79" MouseOverBackground="#F20BA0"  Click="FButton_Click" >WaitingBox</xly:FButton>
            <xly:FButton FIcon="" Margin="3" Width="140" Height="40" Background="#12B512" IsDefault="True" MouseOverBackground="#08EE08" Click="FButton_Click_WindowBase">WindowBase</xly:FButton>

            <xly:FButton FIcon="" Margin="5,0,0,0" CornerRadius="16,0,0,16" AllowsAnimation="True" Click="FButton_Click_Info">Info</xly:FButton>
            <xly:FButton FIcon="" CornerRadius="0" Click="FButton_Click_Question">Question</xly:FButton>
            <xly:FButton FIcon="" CornerRadius="0" Click="FButton_Click_Warning">Warining</xly:FButton>
            <xly:FButton FIcon="" CornerRadius="0,16,16,0" AllowsAnimation="True" Click="FButton_Click_Error">Error</xly: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>

  示例及效果:

            <xly:FButton FIcon="" Margin="5" FIconMargin="0" FIconSize="30" Style="{StaticResource FButton_Transparency}" ></xly:FButton>
            <xly:FButton FIcon="" Margin="5" Style="{StaticResource FButton_Transparency}"></xly:FButton>
            <xly:FButton FIcon="" Margin="5" Style="{StaticResource FButton_Transparency}" IsEnabled="False"></xly:FButton>

            <xly:FButton FIcon="" Margin="3" Style="{StaticResource FButton_Transparency}">如何开启调试模式?</xly:FButton>
            <xly:FButton FIcon="" Margin="3" Style="{StaticResource FButton_Transparency}" IsEnabled="False">设备检测</xly:FButton>
            <xly:FButton FIcon="" Margin="3" Style="{StaticResource FButton_Transparency}">爸爸回来了</xly: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>

示例及效果:

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

  

附录:参考引用

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

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

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

时间: 2024-10-04 11:09:59

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

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

一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 自定义Window窗体样式: 基于自定义窗体实现自定义MessageBox消息提示框: 二.自定义Window窗体样式 自定义的Window窗体效果:   因为WPF默认的窗体比较简陋,大都需要自己实现Window窗体样式效果,基本思路很简单: 第一步:干掉默认样式:WindowStyle = Windo

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

一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: DataGrid自定义样式: ListView自定义样式: 二.DataGrid自定义样式 DataGrid是常用的数据列表显示控件,先看看实现的效果(动态图,有点大): DataGrid控件样式结构包括以下几个部分: 列头header样式 调整列头宽度的列分割线样式 行样式 行头调整高度样式 行头部样式

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

一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: ProcessBar自定义标准样式: ProcessBar自定义环形进度样式: 二.ProcessBar标准样式 效果图: ProcessBar的样式非常简单: <!--ProgressBar Style--> <Style TargetType="ProgressBar" x

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

一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 日历控件Calendar自定义样式: 日期控件DatePicker自定义样式,及Label标签.水印.清除日期功能扩展: 二.Calendar自定义样式 先看看效果: 从上面图可以看出,日历的显示其实有三种状态,如下面的分解图: "日"部分的显示: "月"部分的显示: &qu

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

原文:WPF自定义控件与样式(6)-ScrollViewer与ListBox自定义样式 一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: ScrollViewer的样式拆解及基本样式定义: ListBox集合控件的样式定义: 二.ScrollViewer自定义样式 ScrollViewer在各种列表.集合控件中广泛使用的基础组建,先看看效果图: 如上图,

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

原文:WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表 一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要针对WPF项目开发中图片的各种使用问题,经过总结,把一些经验分享一下.内容包括: WPF常用图像数据源ImageSource的创建: 自定义缩略图控件ThumbnailImage,支持网络图片.大图片.图片异步加载

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

原文:WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式.水印.Label标签.功能扩展 一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要是对文本输入控件进行样式开发,及相关扩展功能开发,主要内容包括: 基本文本框TextBox控件样式及扩展功能,实现了样式.水印.Label标签.功能扩展: 富

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

原文:WPF自定义控件与样式(15)-终结篇 系列文章目录  WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式.水印.Label标签.功能扩展 WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式 WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展

WPF自定义控件与样式(15)-终结篇 &amp; 系列文章索引 &amp; 源码共享

系列文章目录  WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式.水印.Label标签.功能扩展 WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式 WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展 WPF自定义控件与样式(6)-ScrollV