在UWP Windows 10 C#中创建带边框的圆形按钮

14

我正在尝试创建一个圆形按钮,在UWP Windows 10中具有白色边框和透明背景(类似于Windows 8.1中的旧AppBarButtons)。

我找到了一些类似这样的示例:

https://comentsys.wordpress.com/2015/05/23/windows-10-universal-windows-platform-custom-button/

https://social.msdn.microsoft.com/Forums/sqlserver/en-US/cda7a526-5e99-4d4a-a73c-0be4ce77f961/uwpwindows10-how-to-make-button-with-round-edges?forum=wpdevelop&prof=required

但问题出在边框上。 当我将BorderBrush设置为某个颜色时,边框就变成了按钮“矩形”的边框。

有没有办法可以为按钮创建圆形边框?


2
你可以在这里为按钮的"圆角半径属性"提供支持: UserVoice: Add CornerRadius property to Button - Liero
2
似乎在2018年10月的1809版本中可用。 - 27k1
@peterincumbria 如果你已经安装了1809工具包,你可以使用它在早期的目标版本中,只需将以下内容作为“Button”的替换属性即可:Windows10version1809:CornerRadius="90,90,90,90" - kayleeFrye_onDeck
6个回答

13

你正在寻找类似这样的东西吗?

<StackPanel>
    <Button Background="Transparent">
        <StackPanel>
            <Border CornerRadius="10" 
                    Background="Transparent" 
                    BorderBrush="White" 
                    BorderThickness="3">
                <TextBlock Text="MyButton" 
                           Margin="10" 
                           Foreground="White"/>
            </Border>
        </StackPanel>
    </Button>
</StackPanel>

这唯一的缺点就是,如果数字少于两位数,圆圈的大小会有所不同... - Cabuxa.Mapache
@Cabuxa.Mapache,你可以把按钮做得更大一些。 - Shimmy Weitzhandler
FI,您还可以为每个角设置不同的值。 - Kevin VDF

9

有几种方法可以实现这个目标,其中一种是通过使用样式来实现 - 从ContentPresenter中移除BorderBrush并添加一个带有该画笔的Ellipse。XAML示例:

<Page.Resources>
    <Style x:Key="CircleButtonStyle" TargetType="Button">
        <Setter Property="Background" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}"/>
        <Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
        <Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundTransparentBrush}"/>
        <Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}"/>
        <Setter Property="Padding" Value="8,4,8,4"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
        <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
        <Setter Property="FontWeight" Value="Normal"/>
        <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
        <Setter Property="UseSystemFocusVisuals" Value="True"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid x:Name="RootGrid">
                       <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal">
                                    <Storyboard>
                                        <PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="PointerOver">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="BorderCircle">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumLowBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="BorderCircle">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <PointerDownThemeAnimation Storyboard.TargetName="RootGrid"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="BorderCircle">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseMediumLowBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="BorderCircle">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledTransparentBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <ContentPresenter x:Name="ContentPresenter" VerticalAlignment="Center" AutomationProperties.AccessibilityView="Raw" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        <Ellipse x:Name="BorderCircle" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="2"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Page.Resources>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Button Content="text" Width="50" Height="50" BorderBrush="Blue" Style="{StaticResource CircleButtonStyle}"/>
</Grid>

我还在可视状态(VisualStates)中进行了一些更改,以便在点击/禁用时不会显得奇怪。


这会抛出一个 XAML 异常:“无法解析 TargetName BorderCircle”。 - TekGiant
1
应该是 <Ellipse Name="BorderCircle" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="2"/> - TekGiant
@TekGiant 对的,我在复制过程中不知怎么丢了这个。谢谢。 - Romasz

8

我不知道楼主是否还对圆角按钮感兴趣,但为了完整起见,我认为指出另一位用户peterincumbria所说的事情可能对其他用户有所帮助,即在Windows 10的最新版本(1809)中,Control类中有一个新属性:CornerRadius。因此,现在以下代码就足够了:

<Button Content="DEMO"
        Background="Transparent"                    
        BorderThickness="1.0"
        BorderBrush="White"
        CornerRadius="10"
        HorizontalAlignment="Center"
        VerticalAlignment="Center"/>

把这个放在Grid里面,我们就会得到一个圆角按钮,在Page的中间位置。

4

使用版本号为1809及更高版本(即使您的目标版本较早,就像我下面的示例一样),您只需执行以下操作即可创建一个圆形按钮:

<Button
    Content="Stuff"
    Windows10version1809:CornerRadius="90,90,90,90"
    Height="64"
    Width="64">
</Button>

然后,就完成了!

输入图像描述

请确保将此代码添加到XAML顶部的其他xmlns代码中。

xmlns:Windows10version1809="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract, 7)"

0

另一个示例

<Style x:Key="ProfileButtonStyle" TargetType="Button">
        <Setter Property="Background" Value="{StaticResource AppBarHeaderBackground}"/>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="FontFamily" Value="Segoe UI"/>
        <Setter Property="Foreground" Value="{StaticResource SystemControlBackgroundAccentBrush}"></Setter>
        <Setter Property="FontSize" Value="9"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid>
                        <StackPanel Orientation="Vertical">
                            <Grid  Margin="0,0,0,0" >
                                <Ellipse x:Name="ButtonShape" Height="40" Width="40" Fill="#FFFDFCFC" HorizontalAlignment="Center"
                                    Stroke="{StaticResource SystemControlBackgroundAccentBrush}" StrokeThickness="2" VerticalAlignment="Center"/>
                                <!--This glyph is the Contact (head and shoulders silhouette) glyph. -->
                                <TextBlock x:Name="Icon" Text="&#xE13D;" FontFamily="Segoe UI Symbol" FontSize="18" HorizontalAlignment="Center"
                                    VerticalAlignment="Center"/>
                            </Grid>
                            <TextBlock x:Name="ButtonContent" Text="{TemplateBinding Content}" HorizontalAlignment="Center"
                                FontFamily="Segoe UI" FontSize="12"/>
                        </StackPanel>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="PointerOver">
                                    <Storyboard>
                                        <ColorAnimation Duration="0" To="{Binding Source={StaticResource SymbolThemeFontFamily}, Path=Color}" 
                                                        Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" 
                                                        Storyboard.TargetName="ButtonShape" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="ButtonPressed">
                                    <Storyboard>
                                        <ColorAnimation Duration="0" To="#eeeeee" 
                                                        Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" 
                                                        Storyboard.TargetName="ButtonEllipse" />
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

结果

enter image description here

或者创建完全可定制的圆角

//创建一个模板控件XAML设计

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWP.Library2.Controls">
<Style  TargetType="local:CustomRoundedButton">
    <Setter Property="CornerRadius" Value="10,10,10,10"></Setter>
    <Setter Property="Background" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}"/>
    <Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
    <Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundTransparentBrush}"/>
    <Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}"/>
    <Setter Property="Padding" Value="8,4,8,4"/>
    <Setter Property="HorizontalAlignment" Value="Left"/>
    <Setter Property="VerticalAlignment" Value="Center"/>
    <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
    <Setter Property="FontWeight" Value="Normal"/>
    <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
    <Setter Property="UseSystemFocusVisuals" Value="True"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:CustomRoundedButton">
                <Grid x:Name="RootGrid" Background="{TemplateBinding Background}" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}" CornerRadius="{TemplateBinding CornerRadius}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal">
                                <Storyboard>
                                    <PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="PointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumLowBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="RootGrid">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <PointerDownThemeAnimation Storyboard.TargetName="RootGrid"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="RootGrid">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseLowBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledTransparentBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <!--<Rectangle RadiusX="60" RadiusY="60" Fill="{TemplateBinding Background}" Margin="0,0,10,0" />-->
                    <Grid Background="{TemplateBinding Background}" CornerRadius="{TemplateBinding CornerRadius}" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}" ></Grid>
                    <ContentPresenter  CornerRadius="{TemplateBinding CornerRadius}" 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}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

//模板控制器.cs

public sealed class CustomRoundedButton : Button
{
    private Grid _rootGrid = null;
    public CustomRoundedButton()
    {
        this.DefaultStyleKey = typeof(CustomRoundedButton);
    }
    protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        _rootGrid = GetTemplateChild("RootGrid") as Grid;
    }
    public CornerRadius CornerRadius
    {
        get { return (CornerRadius)GetValue(CornerRadiusProperty); }
        set { SetValue(CornerRadiusProperty, value); }
    }
    public static readonly DependencyProperty CornerRadiusProperty =
        DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(CustomRoundedButton), new PropertyMetadata(new CornerRadius(10,10,10,10)));

}

//注册或合并/Themes/Generic.xaml中的字典

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="ms-appx:///UWP.Library2/Controls/CustomRoundedButton/CustomRoundedButton.xaml" />
      </ResourceDictionary.MergedDictionaries>

-1
我刚刚使用的方法是在按钮模板中的“RootGrid”网格中添加CornerRadius。
<Style TargetType="Button" x:Key="RoundedButton">
    ...
    <Grid x:Name="RootGrid" CornerRadius="10" Background="{TemplateBinding Background}"> 
    ...
</Style>

这里没有什么新东西。 - Kevin VDF

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接