• [.NET/WPF] 设置按钮, 以及其他任何包含边框的控件的圆角


    WPF 中, 按钮包含一个 “边框”, 很多时候需要设置按钮的圆角, 但是按钮并没有提供一个属性用来设置边框圆角.

    下面以按钮为例, 列举几种常用的设置圆角的方式.

    通过附加属性

    定义一个附加属性, 然后在各个地方就能直接方便的使用了, 下面是实际使用方式:

    <Button utils.BorderUtils.CornerRadius="3"/>
    
    • 1

    接下来是具体实现代码, 首先是一些工具方法:

    using System.Windows.Media;
    
    namespace System.Windows
    {
        public static class CommonUtils
        {
            public static void RunOnFirstLoaded(this FrameworkElement element, EventHandler handler)
            {
                void Once(object? sender, RoutedEventArgs e)
                {
                    element.Loaded -= Once;
                    handler.Invoke(sender, e);
                }
    
                if (element.IsLoaded)
                    handler.Invoke(element, EventArgs.Empty);
                else
                    element.Loaded += Once;
            }
    
            public static TElement? GetElementFromVisualTree<TElement>(this FrameworkElement control) where TElement : FrameworkElement
            {
                if (control is TElement ele)
                    return ele;
    
                int childrenCount = VisualTreeHelper.GetChildrenCount(control);
                for (int i = 0; i < childrenCount; i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(control, i);
                    if (child is TElement eleChild)
                        return eleChild;
                }
    
                return null;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    然后是 BorderUtils 这个类, 在其中定义 CornerRadius 附加属性:

    using System;
    using System.Windows.Controls;
    using System.Windows.Media;
    
    namespace System.Windows
    {
        public static class BorderUtils
        {
            [AttachedPropertyBrowsableForType(typeof(FrameworkElement))]
            public static CornerRadius GetCornerRadius(DependencyObject obj)
            {
                return (CornerRadius)obj.GetValue(CornerRadiusProperty);
            }
    
            public static void SetCornerRadius(DependencyObject obj, CornerRadius value)
            {
                obj.SetValue(CornerRadiusProperty, value);
            }
    
            // Using a DependencyProperty as the backing store for CornerRadius.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty CornerRadiusProperty =
                DependencyProperty.RegisterAttached("CornerRadius", typeof(CornerRadius), typeof(BorderUtils), new PropertyMetadata(new CornerRadius(), CornerRadiusChanged));
    
            private static void CornerRadiusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                if (d is not FrameworkElement ele)
                    return;
    
                ele.RunOnFirstLoaded((s, _e) =>
                {
                    if (CommonUtils.GetElementFromVisualTree<Border>(ele) is not Border border)
                        return;
    
                    border.CornerRadius = (CornerRadius)e.NewValue;
                });
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    通过资源

    直接在 Button 节点下添加一个 Border 的样式资源, 然后 Button 中的 Border 就会应用这个样式.

    <Button>
      <Button.Resources>
        <Style TargetType="Border">
          "CornerRadius" Value="3" />
        Style>
      Button.Resources>
    Button>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    通过模板

    很麻烦的一种方式, 不推荐

    <Button>
      <Button.Template>
        <ControlTemplate TargetType="{x:Type Button}" >
          <Border BorderBrush="{TemplateBinding Control.BorderBrush}" BorderThickness="1" CornerRadius="7,7,7,7">
            <Border.Background>#FFDDDDDDBorder.Background>
            <ContentPresenter Content="{TemplateBinding ContentControl.Content}" HorizontalAlignment="Center" VerticalAlignment="Center" >ContentPresenter>
          Border>
        ControlTemplate>
      Button.Template>
    Button>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    【考研】操作系统——同步互斥问题(P、V操作)2
    假设检验(Hypothesis Test)
    产品经理如何进行需求管理
    牛逼啊!使用 Redis 实现一个轻量级的搜索引擎
    C语言详解——操作符讲解
    python rb读取文件 base64加密 byte.decode解密,base64解密
    Fiddler抓取手机https包的步骤
    759页14万字智慧大楼弱电智能化规划设计方案
    cmake下的abiFilters和ndk下的abiFilters的区别
    return关键字
  • 原文地址:https://blog.csdn.net/m0_46555380/article/details/130777656