You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建带右下角倒圆角的自定义WPF按钮?

WPF实现右下角带自定义切角/倒圆角的按钮

方法1:用自定义Path重写按钮模板

直接通过ControlTemplate定义按钮外观,用Path绘制带右下角特殊形状的轮廓,同时保留按钮的交互状态(悬停、按下等)。

<Window.Resources>
    <Style x:Key="CustomCornerButtonStyle" TargetType="Button">
        <Setter Property="Width" Value="120"/>
        <Setter Property="Height" Value="40"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid>
                        <!-- 绘制按钮轮廓 -->
                        <Path x:Name="ButtonPath" 
                              Fill="{TemplateBinding Background}"
                              Stroke="{TemplateBinding BorderBrush}"
                              StrokeThickness="{TemplateBinding BorderThickness}">
                            <Path.Data>
                                <!-- 自定义路径:左下角、左上、右上为直角,右下角切10px的角 -->
                                <!-- 如需倒圆角,可将直线替换为ArcTo命令 -->
                                <PathGeometry>
                                    <PathFigure StartPoint="0,0">
                                        <LineSegment Point="0,{TemplateBinding Height}"/>
                                        <LineSegment Point="{TemplateBinding Width},{TemplateBinding Height}"/>
                                        <LineSegment Point="{TemplateBinding Width},10"/>
                                        <LineSegment Point="{Binding Path=Width, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource SubtractConverter}, ConverterParameter=10},0"/>
                                        <LineSegment Point="0,0"/>
                                    </PathFigure>
                                </PathGeometry>
                            </Path.Data>
                        </Path>
                        <!-- 按钮内容 -->
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    </Grid>
                    <!-- 交互状态处理 -->
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="ButtonPath" Property="Fill" Value="#333"/>
                        </Trigger>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter TargetName="ButtonPath" Property="Fill" Value="#555"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <!-- 辅助转换器:计算Width - 10 -->
    <local:SubtractConverter x:Key="SubtractConverter"/>
</Window.Resources>

<!-- 使用示例 -->
<Button Style="{StaticResource CustomCornerButtonStyle}" 
        Background="#111" 
        BorderBrush="#666"
        Content="自定义按钮"/>

对应的转换器C#代码:

public class SubtractConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is double width && double.TryParse(parameter.ToString(), out double subtract))
            return width - subtract;
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

如果需要倒圆角而非直角切角,修改PathFigure的最后两段直线为圆弧:

<PathFigure StartPoint="0,0">
    <LineSegment Point="0,{TemplateBinding Height}"/>
    <LineSegment Point="{TemplateBinding Width},{TemplateBinding Height}"/>
    <ArcSegment Point="{Binding Path=Width, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource SubtractConverter}, ConverterParameter=10},0"
                Size="10,10"
                SweepDirection="Clockwise"/>
    <LineSegment Point="0,0"/>
</PathFigure>

方法2:用Border结合Clip裁剪

如果需要保留按钮的标准布局逻辑,可通过Clip属性裁剪Border的右下角,实现自定义形状:

<Window.Resources>
    <Style x:Key="ClippedButtonStyle" TargetType="Button">
        <Setter Property="Width" Value="120"/>
        <Setter Property="Height" Value="40"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Border x:Name="ButtonBorder"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <!-- 裁剪区域:右下角切角 -->
                        <Border.Clip>
                            <PathGeometry>
                                <PathFigure StartPoint="0,0">
                                    <LineSegment Point="0,{TemplateBinding Height}"/>
                                    <LineSegment Point="{TemplateBinding Width},{TemplateBinding Height}"/>
                                    <LineSegment Point="{TemplateBinding Width},10"/>
                                    <LineSegment Point="{Binding Path=Width, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource SubtractConverter}, ConverterParameter=10},0"/>
                                    <LineSegment Point="0,0"/>
                                </PathFigure>
                            </PathGeometry>
                        </Border.Clip>
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="ButtonBorder" Property="Background" Value="#333"/>
                        </Trigger>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter TargetName="ButtonBorder" Property="Background" Value="#555"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<!-- 使用示例 -->
<Button Style="{StaticResource ClippedButtonStyle}" 
        Background="#111" 
        BorderBrush="#666"
        Content="裁剪式按钮"/>

关键点说明

  • 调整路径中的10数值可以改变右下角切角/圆角的大小
  • 转换器用于动态计算按钮宽度减去切角长度,适配不同按钮尺寸
  • 保留了IsMouseOver、IsPressed等交互状态,确保按钮的基本交互逻辑正常

内容的提问来源于stack exchange,提问作者J4ns323

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 10:08:16