按钮在很多应用程序中都是必不可少的控件,如果给按钮控件添加一些动画效果,比如单击它后会显示一个水波纹扩散的动画效果,那么感觉上更加的高级。本文将介绍一下自定义水波纹按钮控件FlatWaveButton,它是一个UserControl(FlatButton)控件,自身携带UI样式和后台逻辑。下面将详细介绍具体的实现细节。
1 WPF项目结构
基于之前创建的WPF示例项目,在其中创建一个新的关于FlatWaveButton的用户控件项目文件。添加过程如下图所示:
添加成功后,本项目文件结构,如下图所示:
与之前的自定义控件不同,用户控件类型的项目文件UI和后台逻辑是在一起的,这样也非常的方便。另外,这种方式创建的自定义控件不需要将其注册到Generic.xaml文件中。
2 WPF FlatWaveButton实现
首先,在控件的UI界面上,UserControl类的控件原生带有UI布局,即像一个窗口一样,可以通过拖入已有的控件进行UI设计,因此从布局到功能上都更加的方便。FlatWaveButton控件,布局界面如下:
其中的核心代码如下:
<local:FlatButtonx: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><ControlTemplateTargetType="{x:Type local:FlatButton}"><GridClipToBounds="True"Background="Transparent"MouseLeftButtonDown="Wave_MouseClick"><BorderCornerRadius="{TemplateBinding CornerRadius}"Background="{TemplateBinding Background}"><ContentPresenterHorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/></Border><PathFill="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=WaveBackground}"Name="Wave_Path"><Path.Data><EllipseGeometryx: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核心代码,具体如下所示:
usingSystem; usingSystem.Windows; usingSystem.Windows.Input; usingSystem.Windows.Media; usingSystem.Windows.Media.Animation; usingSystem.Windows.Shapes; namespaceYd.WpfControls{ /// <summary>/// FlatWaveButton.xaml 的交互逻辑/// </summary>publicpartialclassFlatWaveButton : FlatButton { publicFlatWaveButton() { InitializeComponent(); } publicstaticreadonlyDependencyPropertyWaveBackgroundProperty=DependencyProperty.Register("WaveBackground", typeof(Brush), typeof(FlatWaveButton), newPropertyMetadata(Brushes.White)); /// <summary>/// 水波背景颜色/// </summary>publicBrushWaveBackground { get { return (Brush)GetValue(WaveBackgroundProperty); } set { SetValue(WaveBackgroundProperty, value); } } privatevoidWave_MouseClick(objectsender, MouseButtonEventArgse) { EllipseGeometrymyellipse=Template.FindName("Wave_Ellipse", this) asEllipseGeometry; myellipse.Center=Mouse.GetPosition(this); DoubleAnimationdh=newDoubleAnimation() { From=0, To=138, Duration=newDuration(TimeSpan.FromSeconds(1.5)) }; myellipse.BeginAnimation(EllipseGeometry.RadiusXProperty, dh); DoubleAnimationdh02=newDoubleAnimation() { From=0.35, To=0, Duration=newDuration(TimeSpan.FromSeconds(1.5)) }; Pathmypath=Template.FindName("Wave_Path", this) asPath; 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部分示例代码如下:
<Windowxmlns="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"><GridBackground="Green"><WpfControls:FlatWaveButtonContent="FlatWaveButton"HorizontalAlignment="Center"Margin="0,88,0,0"VerticalAlignment="Top"Height="66"Width="300"/></Grid></Window>
运行界面如下: