wpf 水波纹按钮

模板

<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>
上一篇
下一篇