如何创建带右下角倒圆角的自定义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
相关产品推荐
相关产品推荐

