模板
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:waterRippleButtonCtrls="clr-namespace:WpfDemoApp.WaterRippleButtonCtrls">
<!-- 定义模板 -->
<ControlTemplate x:Key="WaterRippleButtonControlTemplate" TargetType="waterRippleButtonCtrls:WaterRippleButton">
<Border
x:Name="RootBorder"
Background="{TemplateBinding Background}"
BorderBrush="CornflowerBlue" BorderThickness="1" ClipToBounds="True" CornerRadius="5"
SnapsToDevicePixels="True">
<Grid ClipToBounds="True">
<!-- 水波纹, 这里使用 path 中的圆形,并调用宽度与高度绑定,动画时调整宽度值 -->
<Path
x:Name="ButtonPath"
Fill="DarkBlue" Opacity=".5">
<Path.Data>
<EllipseGeometry
x:Name="ButtonEllipseGeometry"
RadiusX="15"
RadiusY="{Binding RelativeSource={RelativeSource Self}, Path=RadiusX}" />
</Path.Data>
</Path>
<!-- 正儿八经内容 -->
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Panel.ZIndex="0" />
</Grid>
</Border>
<!-- 鼠标移上变色 -->
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="RootBorder" Property="Background" Value="DodgerBlue" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- 定义样式 -->
<Style BasedOn="{StaticResource {x:Type Button}}" TargetType="waterRippleButtonCtrls:WaterRippleButton">
<Setter Property="Template" Value="{StaticResource WaterRippleButtonControlTemplate}" />
</Style>
</ResourceDictionary>
代码
static WaterRippleButton()
{
// 使用自定义模板
DefaultStyleKeyProperty.OverrideMetadata(typeof(WaterRippleButton), new FrameworkPropertyMetadata(typeof(WaterRippleButton)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
if (this.Template.FindName("ButtonPath", this) is Path path)
{
// 先隐藏水波纹
path.Opacity = 0;
}
this.PreviewMouseLeftButtonUp += this.OnPreviewMouseLeftButtonUp;
}
private void OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (this.Template.FindName("ButtonEllipseGeometry", this) is not EllipseGeometry geometry)
{
return;
}
// 设置 水波纹中心点为鼠标点击点
geometry.Center = Mouse.GetPosition(this);
// 设置 水波纹宽度扩散动画
var radiusXanimation = new DoubleAnimation
{
From = 0,
To = 150,
EasingFunction = new PowerEase { EasingMode = EasingMode.EaseIn, },
Duration = TimeSpan.FromSeconds(0.6),
};
geometry.BeginAnimation(EllipseGeometry.RadiusXProperty, radiusXanimation);
if (this.Template.FindName("ButtonPath", this) is not Path path)
{
return;
}
// 设置 水波纹隐藏动画
var opacityAnimation = new DoubleAnimation
{
From = 0.5,
To = 0,
Duration = TimeSpan.FromSeconds(0.8),
};
path.BeginAnimation(OpacityProperty, opacityAnimation);
}
使用
<Grid>
<local:WaterRippleButton
Width="120" Height="40"
HorizontalAlignment="Center" VerticalAlignment="Center"
Background="#ff007acc" Content="按 钮" Foreground="White" />
</Grid>