首页 > 解决方案 > 如何以编程方式设置按钮样式(第 2 部分)?

问题描述

我正在尝试实现这个答案(关于如何圆角按钮),但是以编程方式。

我有:

Style style = new Style(typeof(Button));
style.Setters.Add(new Setter(Border.CornerRadiusProperty, new CornerRadius(5)));
button.Style = style;

button按钮在哪里。(惊喜!)

不幸的是,这对按钮没有任何作用......

标签: c#.netwpf

解决方案


Border.CornerRadiusProperty是 Border 的依赖属性,在 Button 上设置它不会做任何事情。

如果将编辑光标放在窗口 XAML 中的按钮上,转到其属性页,单击“杂项 -> 模板”右侧的小方块并选择“转换为新资源”,然后 VS 将展开模板作为本地资源供您查看和编辑。看一眼这个模板可以看出,虽然模板中存在边框,但它只支持边框画笔和粗细:

<Border x:Name="border"
    BorderBrush="{TemplateBinding BorderBrush}"
    BorderThickness="{TemplateBinding BorderThickness}"
    Background="{TemplateBinding Background}"
    SnapsToDevicePixels="True">

因此,如果您想在按钮上支持角点,则需要修改此模板并为其创建一个属性以绑定到该属性,然后您可以在按钮声明中设置该属性。一种方法是通过子类化Button并添加诸如BorderCornerRadius那里的属性。另一种方法是创建一个附加属性,然后可以将其应用于任何框架元素,包括 Button:

public static class ButtonHelper
{
    public static CornerRadius GetBorderCornerRadius(DependencyObject obj)
    {
        return (CornerRadius)obj.GetValue(BorderCornerRadiusProperty);
    }

    public static void SetBorderCornerRadius(DependencyObject obj, CornerRadius value)
    {
        obj.SetValue(BorderCornerRadiusProperty, value);
    }

    public static readonly DependencyProperty BorderCornerRadiusProperty =
        DependencyProperty.RegisterAttached("BorderCornerRadius", typeof(CornerRadius), typeof(ButtonHelper), new PropertyMetadata(new CornerRadius(0)));
}

然后,您可以修改模板以使用此附加属性来设置边框角半径:

<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
        CornerRadius="{Binding (local:ButtonHelper.BorderCornerRadius), RelativeSource={RelativeSource TemplatedParent}}"
        ... etc ...

现在您可以使用它来代替Border.CornerRadius. 要在 XAML 中执行此操作,您只需执行以下操作:

<Button x:Name="theButton" Width="100" Height="100"
        Template="{DynamicResource ButtonControlTemplate1}"
        local:ButtonHelper.BorderCornerRadius="20" />

或者您可以在代码隐藏中执行此操作,如上面的示例代码(不要忘记您仍然需要覆盖控件模板):

Style style = new Style(typeof(Button));
style.Setters.Add(new Setter(ButtonHelper.BorderCornerRadiusProperty, new CornerRadius(20)));
theButton.Style = style;

更新:您链接到的答案通过更改默认Border样式的属性来工作,您可以通过这样做在代码中实现:

Style style = new Style(typeof(Border));
style.Setters.Add(new Setter(Border.CornerRadiusProperty, new CornerRadius(20)));
theButton.Resources.Add(typeof(Border), style);

这样做的问题是,它将应用于该按钮中的所有边框,不仅是按钮模板,还包括内容或其 DataTemplates 等中的任何边框。迟早,随着 GUI 复杂性的增加,这可能会回到困扰你。总的来说,我发现虽然像上面这样的捷径可以在短期内完成工作,但通过正确地做事,你会遇到更少的问题。


推荐阅读