XAML 圆边按钮,两侧有完美的半圆

XAML button with rounded edged with perfect semicircle at the sides

一段时间以来,我一直在尝试创建一个圆边按钮,其圆边实际上是半圆。
我实现这个的想法是将 BorderCornerRadius 绑定到按钮高度的一半(我知道我无法在 XAML 中进行计算,除了可能转换器)。唉,这似乎是不可能的,因为 TemplateBinding 没有提出任何建议。

<ControlTemplate TargetType="Button">
    <Grid>
        <Border CornerRadius={???}>
            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                              Margin="{TemplateBinding Padding}"
                              FontSize="{TemplateBinding FontSize}"
                              FontFamily="{TemplateBinding FontFamily}" />
        </Border>
    </Grid>
</ControlTemplate>

也许我可能需要创建一个从具有 CornerRadius 依赖性 属性 的按钮派生的新控件。但在我继续之前,有没有办法在 XAML 中实现它?
顺便说一下,如果重要的话,我是为 UWP 应用程序做的吗?

But before I go ahead, is there anyway to achieve it in XAML?

是的,我认为这是可能的。但是需要转换器

I know there's no way I can do a calculation in XAML, except maybe a converter

是的,我们需要在转换器中计算,CornerRadius是一个CornerRadius类型,我们不能直接绑定Height/2的double类型。这里我用Button的高度来计算半径。

My idea of implementing this is to bind the CornerRadius of the Border to the half the height of the button.

我觉得ButtonControlTemplate没必要用BorderGridContentPresenter也有CornerRadius 属性.

例如这里:

<ControlTemplate TargetType="Button">
    <Grid x:Name="RootGrid" Background="{TemplateBinding Background}"
          CornerRadius="{Binding Height, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource cvt}}">
        <ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw"
                          BorderBrush="{TemplateBinding BorderBrush}"
                          BorderThickness="{TemplateBinding BorderThickness}"
                          ContentTemplate="{TemplateBinding ContentTemplate}"
                          ContentTransitions="{TemplateBinding ContentTransitions}"
                          Content="{TemplateBinding Content}"
                          HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                          Padding="{TemplateBinding Padding}"
                          VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                          CornerRadius="{Binding Height, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource cvt}}" />
    </Grid>
</ControlTemplate>

<local:HeightToCornerRadiusConverter x:Key="cvt" />

我的HeightToCornerRadiusConverter是这样的:

public class HeightToCornerRadiusConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var height = (double)value;
        CornerRadius radius = new CornerRadius(height / 2);
        return radius;
    }

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

这里有个问题,大家可以看到CornerRadius绑定了ButtonHeight,所以需要设置高度Button 当我们使用这种风格时。