WPF 斜角border

最近看了一些科技感UI设计,其中很多的按钮都不是常见的圆角边,而是斜角边。查了一下,wpf中好像没有现成的斜角border,网上也没搜到现成的,于是自己写了点时间做了一个,写的较简单,有一些bug(主要是没有去管一些极值情况),但也基本可用了。

下面与大家分享一下代码:

先上效果:

后台类:

    /// <summary>
    /// 斜角Border
    /// </summary>
    class BeveledBorder : Decorator
    {
        public Brush BorderBrush
        {
            get { return (Brush)GetValue(BorderBrushProperty); }
            set { SetValue(BorderBrushProperty, value); }
        }

        public static readonly DependencyProperty BorderBrushProperty =
            Border.BorderBrushProperty.AddOwner(typeof(BeveledBorder), new PropertyMetadata(Brushes.Transparent, CommonPropertyChanged));

        public Thickness BorderThickness
        {
            get { return (Thickness)GetValue(BorderThicknessProperty); }
            set { SetValue(BorderThicknessProperty, value); }
        }

        public static readonly DependencyProperty  BorderThicknessProperty =
            Border.BorderThicknessProperty.AddOwner(typeof(BeveledBorder), new PropertyMetadata(new Thickness(), CommonPropertyChanged));

        public Brush Background
        {
            get { return (Brush)GetValue(BackgroundProperty); }
            set { SetValue(BackgroundProperty, value); }
        }

        public static readonly DependencyProperty BackgroundProperty =
            Control.BackgroundProperty.AddOwner(typeof(BeveledBorder), new PropertyMetadata(Brushes.Transparent, CommonPropertyChanged));

        public CornerRadius CornerRadius
        {
            get { return (CornerRadius)GetValue(CornerRadiusProperty); }
            set { SetValue(CornerRadiusProperty, value); }
        }

        public static readonly DependencyProperty CornerRadiusProperty =
            Border.CornerRadiusProperty.AddOwner(typeof(BeveledBorder), new PropertyMetadata(new CornerRadius(), CommonPropertyChanged));

        private static void CommonPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as BeveledBorder)._isrendersizechanged = true;
            (d as BeveledBorder).InvalidateVisual();
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);

            if (_isrendersizechanged)
            {
                _isrendersizechanged = false;
                UpdateGeometry(RenderSize);
            }

            Pen pTop = new Pen(BorderBrush, BorderThickness.Top);
            drawingContext.DrawGeometry(Background, pTop, _currenGeometry);
        }

        protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
        {
            base.OnRenderSizeChanged(sizeInfo);
            _isrendersizechanged = true;
        }

        private void UpdateGeometry(Size nsize)
        {
            if (_currenGeometry == null)
            {
                _currenGeometry = new PathGeometry();
                _currenGeometry.Figures.Add(new PathFigure());
                _currenGeometry.Figures[0].IsClosed = true;
            }
            else
            {
                _currenGeometry.Figures[0].Segments.Clear();
            }

            if (CornerRadius == null)
            {                  _currenGeometry.Figures[0].StartPoint = new Point(0, 0);

            _currenGeometry.Figures[0].Segments.Add(ToLineSegment(new Point(nsize.Width, 0)));
                  _currenGeometry.Figures[0].Segments.Add(ToLineSegment(new Point(nsize.Width, nsize.Height)));
                  _currenGeometry.Figures[0].Segments.Add(ToLineSegment(new Point(0, nsize.Height)));

            }
            else
            {
                _currenGeometry.Figures[0].StartPoint = new Point(CornerRadius.TopLeft, 0);

                if (CornerRadius.TopRight <= 0)
                {
                    _currenGeometry.Figures[0].Segments.Add(ToLineSegment(new Point(nsize.Width, 0)));
                }
                else
                {
                    _currenGeometry.Figures[0].Segments.Add(ToLineSegment(new Point(nsize.Width - CornerRadius.TopRight, 0)));
                    _currenGeometry.Figures[0].Segments.Add(ToLineSegment(new Point(nsize.Width, CornerRadius.TopRight)));
                }

                if (CornerRadius.BottomRight <= 0)
                {
                    _currenGeometry.Figures[0].Segments.Add(ToLineSegment(new Point(nsize.Width, nsize.Height)));
                }
                else
                {
                    _currenGeometry.Figures[0].Segments.Add(ToLineSegment(new Point(nsize.Width, nsize.Height - CornerRadius.BottomRight)));
                    _currenGeometry.Figures[0].Segments.Add(ToLineSegment(new Point(nsize.Width - CornerRadius.BottomRight, nsize.Height)));
                }

                if (CornerRadius.BottomLeft <= 0)
                {
                    _currenGeometry.Figures[0].Segments.Add(ToLineSegment(new Point(0, nsize.Height)));
                }
                else
                {
                    _currenGeometry.Figures[0].Segments.Add(ToLineSegment(new Point(CornerRadius.BottomLeft, nsize.Height)));
                    _currenGeometry.Figures[0].Segments.Add(ToLineSegment(new Point(0, nsize.Height - CornerRadius.BottomLeft)));
                }

                if (CornerRadius.TopLeft > 0)
                {
                    _currenGeometry.Figures[0].Segments.Add(ToLineSegment(new Point(0, CornerRadius.TopLeft)));
                }
            }
        }

        private LineSegment ToLineSegment(Point pt)
        {
            return new LineSegment(pt, true);
        }

        private PathGeometry _currenGeometry = null;
        private bool _isrendersizechanged = true;
    }

前台调用:

    <Window.Resources>
        <Style TargetType="{x:Type local:BeveledBorder}">
            <Setter Property="Background" Value="#90000000" />
            <Setter Property="BorderBrush" Value="Black"/>
            <Setter Property="BorderThickness" Value="2"/>
            <Setter Property="Margin" Value="2" />
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="#90FF0000"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <UniformGrid Rows="1" VerticalAlignment="Center" MinHeight="50">

        <local:BeveledBorder
                          BorderThickness="2"
                          Margin="2"
                          CornerRadius="10,0,10,0">
            <TextBlock Text="123" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </local:BeveledBorder>

        <local:BeveledBorder
                          BorderThickness="2"
                          Margin="2"
                          CornerRadius="10,10,10,10"/>

        <local:BeveledBorder
                          BorderThickness="2"
                          Margin="2"
                          CornerRadius="10,20,10,20"/>

        <local:BeveledBorder
                          BorderThickness="2"
                          Margin="2"
                          CornerRadius="0,15,0,15"/>

        <local:BeveledBorder Width="40" Height="40"
                          BorderThickness="2"
                          Margin="2"
                          CornerRadius="10,10,10,10"/>

    </UniformGrid>

原文地址:https://www.cnblogs.com/GuoRL/p/9115951.html

时间: 2025-01-16 00:55:05

WPF 斜角border的相关文章

WPF 使用Border创建圆角边框

创建圆角边框可以通过设置border的 CornerRadius 属性其边框呈现圆角样式 代码: <Border Height="50" Background="Red" CornerRadius="20,0,0,0" > 效果图: 位置说明: CornerRadius="左,右,右下,左下" 提示: 如过圆角处有颜色,请将外层容器的背景色设置为透明 Background="Transparent&quo

WPF 通过Border来画边框

WPF有自己的表格控件DataGrid.ListBox等,如果只是简单的需求,可以通过Border控件来画边框. 比如我们需要给上面的控件加上边框. <Window x:Class="WpfApplication5.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/win

WPF 采用Border创建圆角

通过设置可以创建圆角border的CornerRadius属性其边框呈现圆角样式 代码: <Border Height="50" Background="Red" CornerRadius="20,0,0,0" > 效果图: 位置说明: CornerRadius="左,右,右下,左下" 提示: 如过圆角处有颜色,请将外层容器的背景色设置为透明 Background="Transparent" 版

WPF使用四边不同颜色的Border

正常情况下WPF自带的Border都能满足我们日常使用.但某些情况下遇到比较复杂的需求时候原生的效果还是不能满足我们的需求.例如以下这种立体边框: 当然如果这种尺寸是固定的,我们只需要美工提供图片就可以了,但如果尺寸是可以动态变动的我们就不能使用图片作为背景了,因为背景边框也是会拉伸的,谁叫咋们的WPF不能像IOS开发那样设置一个值边框就不会拉伸······· 好吧,我们只有自己动手实现一个四个边框不同颜色的border来实现了. 1.首先,我们创建一个类,继承自Borde.再新建4个边框的Br

WPF学习:3.Border &amp; Brush

上一章<WPF学习:2.Layout-Panels-Countainers>主要介绍了布局,容器和面板.这一章主要开始介绍Border(边界)和Brush(画刷). 代码地址:http://www.cnblogs.com/keylei203/archive/2013/03/12/keylei203.html 引言 在任何WPF的程序设计中,Border都占主要部分,一般都会使用很多Border装饰用户界面.从直接在window上放置borders到在ListBoxItem上放置Borders,

WPF中设置Border的BorderThickness属性会让背景图片产生模糊感

1 <!--设置BorderThickness会让border的Background图片看起来有模糊感--> 2 <Border x:Name="border" 3 BorderBrush="{x:Null}" 4 BorderThickness="1" 5 Background="{TemplateBinding Background}" 6 RenderTransformOrigin="0.5,

WPF入门教程系列十——布局之Border与ViewBox(五)

九. Border Border 是一个装饰的控件,此控件绘制边框及背景,在 Border 中只能有一个子控件,若要显示多个子控件,需要将一个附加的 Panel 控件放置在父 Border 中.然后可以将子控件放置在该 Panel控件中. Border 的几个重要属性: Background:用用一个 Brush 对象来绘制背景 : BorderBrush:用一个Brush 对象来绘制边框 : BorderThickness:此属性设置 Border 边框的大小: CornerRadius:此属

wpf Border 边框

<Border Grid.Row="0" Grid.Column="0" BorderBrush="AntiqueWhite" BorderThickness="5"></Border> 上面代码的意思是给Grid第1行第一列添加一个颜色为AntiqueWhite,四边的宽度都是5的边框 BorderThickness的值可以赋值多个,如果赋四个值的话 第一个值代表控件的左边框大小 第二个值代表控件上边

《深入浅出WPF》笔记——绘画与动画

<深入浅出WPF>笔记——绘画与动画 本篇将记录一下如何在WPF中绘画和设计动画,这方面一直都不是VS的强项,然而它有一套利器Blend:这方面也不是我的优势,幸好我有博客园,能记录一下学习的过程.在本记录中,为了更好的理解绘画与动画,多数的例子还是在VS里面敲出来的.好了,不废话了,现在开始. 一.WPF绘画 1.1基本图形 在WPF中可以绘制矢量图,不会随窗口或图型的放大或缩小出现锯齿或变形,除此之外,XAML绘制出来的图有个好处就是便于修改,当图不符合要求的时间,通常改某些属性就可以完成