WPF自定義控件與樣式(2)-自定義按鈕FButton


一.前言.效果圖

  申明: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(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)));
        }
    }
View Code

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

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="&#xe602;" Margin="3">系統換轉</core:FButton>
            <core:FButton FIcon="&#xe628;" Margin="3" Width="140" Height="40" Background="#771C79" MouseOverBackground="#F20BA0"  Click="FButton_Click" >WaitingBox</core:FButton>
            <core:FButton FIcon="&#xe629;" Margin="3" Width="140" Height="40" Background="#12B512" IsDefault="True" MouseOverBackground="#08EE08" Click="FButton_Click_WindowBase">WindowBase</core:FButton>

            <core:FButton FIcon="&#xe64f;" Margin="5,0,0,0" CornerRadius="16,0,0,16" AllowsAnimation="True" Click="FButton_Click_Info">Info</core:FButton>
            <core:FButton FIcon="&#xe628;" CornerRadius="0" Click="FButton_Click_Question">Question</core:FButton>
            <core:FButton FIcon="&#xe628;" CornerRadius="0" Click="FButton_Click_Warning">Warining</core:FButton>
            <core:FButton FIcon="&#xe629;" 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="&#xe627;" Margin="5" FIconMargin="0" FIconSize="30" Style="{StaticResource FButton_Transparency}" ></core:FButton>
            <core:FButton FIcon="&#xe628;" Margin="5" Style="{StaticResource FButton_Transparency}"></core:FButton>
            <core:FButton FIcon="&#xe629;" Margin="5" Style="{StaticResource FButton_Transparency}" IsEnabled="False"></core:FButton>


            <core:FButton FIcon="&#xe60e;" Margin="3" Style="{StaticResource FButton_Transparency}">如何開啟調試模式?</core:FButton>
            <core:FButton FIcon="&#xe617;" Margin="3" Style="{StaticResource FButton_Transparency}" IsEnabled="False">設備檢測</core:FButton>
            <core:FButton FIcon="&#xe629;" 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="&#xe617;" 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

個人能力有限,本文內容僅供學習、探討,歡迎指正、交流。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM