天天看點

WPF自定義控件09:FlatWaveButton

  按鈕在很多應用程式中都是必不可少的控件,如果給按鈕控件添加一些動畫效果,比如單擊它後會顯示一個水波紋擴散的動畫效果,那麼感覺上更加的進階。本文将介紹一下自定義水波紋按鈕控件FlatWaveButton,它是一個UserControl(FlatButton)控件,自身攜帶UI樣式和背景邏輯。下面将詳細介紹具體的實作細節。

1 WPF項目結構

    基于之前建立的WPF示例項目,在其中建立一個新的關于FlatWaveButton的使用者控件項目檔案。添加過程如下圖所示:

WPF自定義控件09:FlatWaveButton

添加成功後,本項目檔案結構,如下圖所示:

WPF自定義控件09:FlatWaveButton

與之前的自定義控件不同,使用者控件類型的項目檔案UI和背景邏輯是在一起的,這樣也非常的友善。另外,這種方式建立的自定義控件不需要将其注冊到Generic.xaml檔案中。

2 WPF FlatWaveButton實作

    首先,在控件的UI界面上,UserControl類的控件原生帶有UI布局,即像一個視窗一樣,可以通過拖入已有的控件進行UI設計,是以從布局到功能上都更加的友善。FlatWaveButton控件,布局界面如下:

WPF自定義控件09:FlatWaveButton

其中的核心代碼如下:

<local:FlatButton x:Class="Yd.WpfControls.FlatWaveButton"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Yd.WpfControls"
             mc:Ignorable="d" 
             CornerRadius="16"
             VerticalContentAlignment ="Center"
             HorizontalContentAlignment="Center"
             d:DesignHeight="32" d:DesignWidth="100">
    <local:FlatButton.Template>
        <ControlTemplate TargetType="{x:Type local:FlatButton}">
            <Grid ClipToBounds="True" Background="Transparent" MouseLeftButtonDown="Wave_MouseClick" >
                <Border CornerRadius="{TemplateBinding CornerRadius}" Background="{TemplateBinding Background}">
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Border>
                <Path Fill="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=WaveBackground}" 
                      Name="Wave_Path" >
                    <Path.Data>
                        <EllipseGeometry x:Name="Wave_Ellipse" RadiusX="0" 
                                         RadiusY="{Binding RelativeSource={RelativeSource Mode=Self},Path=RadiusX}">

                        </EllipseGeometry>
                    </Path.Data>
                </Path>
            </Grid>
        </ControlTemplate>
    </local:FlatButton.Template>
</local:FlatButton>
      

其中使用者控件預設的usercontrol修改為local:FlatButton,且自定義了ControlTemplate模闆資訊,這裡用Path進行了路徑的定義,其中的路徑資料是通過EllipseGeometry實作的,它通過動态修改RadiusX和RadiusY實作一個動态水波紋的效果。當然這個動畫背景進行實作。下面給出FlatWaveButton.xaml.cs核心代碼,具體如下所示:

using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Yd.WpfControls
{
    /// <summary>
    /// FlatWaveButton.xaml 的互動邏輯
    /// </summary>
    public partial class FlatWaveButton : FlatButton
    {
        public FlatWaveButton()
        {
            InitializeComponent();
        }
        public static readonly DependencyProperty WaveBackgroundProperty =
           DependencyProperty.Register("WaveBackground", typeof(Brush), typeof(FlatWaveButton),
               new PropertyMetadata(Brushes.White));
        /// <summary>
        /// 水波背景顔色
        /// </summary>
        public Brush WaveBackground
        {
            get { return (Brush)GetValue(WaveBackgroundProperty); }
            set { 
                SetValue(WaveBackgroundProperty, value);
            }
        }
        private void Wave_MouseClick(object sender, MouseButtonEventArgs e)
        {
            EllipseGeometry myellipse = Template.FindName("Wave_Ellipse", this) as EllipseGeometry;
            myellipse.Center = Mouse.GetPosition(this);
            DoubleAnimation dh = new DoubleAnimation()
            {
                From = 0,
                To = 138,
                Duration = new Duration(TimeSpan.FromSeconds(1.5))
            };
            myellipse.BeginAnimation(EllipseGeometry.RadiusXProperty, dh);

            DoubleAnimation dh02 = new DoubleAnimation()
            {
                From = 0.35,
                To = 0,
                Duration = new Duration(TimeSpan.FromSeconds(1.5))
            };

            Path mypath = Template.FindName("Wave_Path", this) as Path;
            mypath.BeginAnimation(OpacityProperty, dh02);
        }
    }
}
      

當我們單擊控件時,首先通過Template.FindName("Wave_Ellipse", this) as EllipseGeometry擷取到名為Wave_Ellipse對象,并根據Mouse.GetPosition(this)擷取到滑鼠位置,作為myellipse的中心,這樣圓形就從滑鼠位置進行生成。關于動畫是用内置的DoubleAnimation實作的,它有兩個作用,一個是動态修改EllipseGeometry.RadiusXProperty的屬性值,即半徑大小。另外一個就是動态修改名為Wave_Path的Path對象的透明度。

3 WPF FlatWaveButton測試

    首先,需要重新生成一下項目檔案,然後在WpfControls項目中添加一個視窗Window7,并在此視窗中添加自定義控件FlatWaveButton,Window7.xaml部分示例代碼如下:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfControls"
        xmlns:WpfControls="clr-namespace:Yd.WpfControls;assembly=Yd.WpfControls" 
        x:Class="WpfControls.Window7"
        mc:Ignorable="d"
        Title="Window7" Height="350" Width="500">
    <Grid Background="Green">
        <WpfControls:FlatWaveButton Content="FlatWaveButton" HorizontalAlignment="Center" 
            Margin="0,88,0,0" VerticalAlignment="Top" Height="66" Width="300"/>
    </Grid>
</Window>
      

運作界面如下:

WPF自定義控件09:FlatWaveButton