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

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

先上效果:

前台代码:

    <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 CornerRadius="10,0,10,0">
<TextBlock Text="123" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</local:BeveledBorder> <local:BeveledBorder CornerRadius="10,10,10,10"/> <local:BeveledBorder CornerRadius="10,20,10,20"/> <local:BeveledBorder CornerRadius="0,15,0,15"/> <local:BeveledBorder Width="40" Height="40"
CornerRadius="10,10,10,10"/> </UniformGrid>

后台类:

    /// <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[].IsClosed = true;
}
else
{
_currenGeometry.Figures[].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[].StartPoint = new Point(CornerRadius.TopLeft, ); if (CornerRadius.TopRight <= )
{
_currenGeometry.Figures[].Segments.Add(ToLineSegment(new Point(nsize.Width, )));
}
else
{
_currenGeometry.Figures[].Segments.Add(ToLineSegment(new Point(nsize.Width - CornerRadius.TopRight, )));
_currenGeometry.Figures[].Segments.Add(ToLineSegment(new Point(nsize.Width, CornerRadius.TopRight)));
} if (CornerRadius.BottomRight <= )
{
_currenGeometry.Figures[].Segments.Add(ToLineSegment(new Point(nsize.Width, nsize.Height)));
}
else
{
_currenGeometry.Figures[].Segments.Add(ToLineSegment(new Point(nsize.Width, nsize.Height - CornerRadius.BottomRight)));
_currenGeometry.Figures[].Segments.Add(ToLineSegment(new Point(nsize.Width - CornerRadius.BottomRight, nsize.Height)));
} if (CornerRadius.BottomLeft <= )
{
_currenGeometry.Figures[].Segments.Add(ToLineSegment(new Point(, nsize.Height)));
}
else
{
_currenGeometry.Figures[].Segments.Add(ToLineSegment(new Point(CornerRadius.BottomLeft, nsize.Height)));
_currenGeometry.Figures[].Segments.Add(ToLineSegment(new Point(, nsize.Height - CornerRadius.BottomLeft)));
} if (CornerRadius.TopLeft > )
{
_currenGeometry.Figures[].Segments.Add(ToLineSegment(new Point(, CornerRadius.TopLeft)));
}
}
} private LineSegment ToLineSegment(Point pt)
{
return new LineSegment(pt, true);
} private PathGeometry _currenGeometry = null;
private bool _isrendersizechanged = true;
}

WPF 斜角border的更多相关文章

  1. WPF 通过Border来画边框

    WPF有自己的表格控件DataGrid.ListBox等,如果只是简单的需求,可以通过Border控件来画边框. 比如我们需要给上面的控件加上边框. <Window x:Class=" ...

  2. WPF 采用Border创建圆角

    通过设置可以创建圆角border的CornerRadius属性其边框呈现圆角样式 代码: <Border Height="50" Background="Red&q ...

  3. WPF使用border画框

    以前的界面中使用的框大都是由美工做好的,但是这样就遇到几个问题: 框只是换一个颜色,就需要多做出一张图,资源包中也要多一个图片资源: 文字的数量会改变,用一张固定的图进行拉伸,边角处会变得越来越不尽如 ...

  4. WPF参考

    web 调用本地exe 程序,传入参数https://www.cnblogs.com/anjou/p/10045177.html WPF常用控件样式https://www.cnblogs.com/s0 ...

  5. WPF绘制自定义窗口

    原文:WPF绘制自定义窗口 WPF是制作界面的一大利器,下面就用WPF模拟一下360的软件管理界面,360软件管理界面如下: 界面不难,主要有如下几个要素: 窗体的圆角 自定义标题栏及按钮 自定义状态 ...

  6. WPF学习:3.Border & Brush

    上一章<WPF学习:2.Layout-Panels-Countainers>主要介绍了布局,容器和面板.这一章主要开始介绍Border(边界)和Brush(画刷). 代码地址:http:/ ...

  7. 【C#】WPF的xaml中定义的Trigger为什么有时候会不管用,如Border的MouseOver之类的

    原文:[C#]WPF的xaml中定义的Trigger为什么有时候会不管用,如Border的MouseOver之类的 初学WPF,知道一些控件可以通过定义Style的Trigger改变要显示的样式,但是 ...

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

    九. Border Border 是一个装饰的控件,此控件绘制边框及背景,在 Border 中只能有一个子控件,若要显示多个子控件,需要将一个附加的 Panel 控件放置在父 Border 中.然后可 ...

  9. WPF控件---Border应用

    内容模型:Border 只能具有一个子元素.若要显示多个子元素, 需要将一个容器元素放置在父元素Border中. <Grid> <Border BorderBrush="B ...

随机推荐

  1. Activiti任务认领

    Activiti任务认领 TaskService taskService; taskService.setAssignee(String taskId, String userId);taskServ ...

  2. 日志分析工具、日志管理系统、syslog分析

    日志分析工具.日志管理系统.syslog分析 系统日志(Syslog)管理是几乎所有企业的重要需求.系统管理员将syslog看作是解决网络上系统日志支持的系统和设备性能问题的关键资源.人们往往低估了对 ...

  3. 再读c++primer plus 004

    第九章  内存模型和名称空间 1.如果文件名包含在尖括号中,则c++编译器将在存储标准头文件的主机系统的文件系统中查找,但如果文件名包含在双引号中,则编译器将首先查找当前的工作目录或源代码目录(或其他 ...

  4. Django的学习(六)————templates过滤器、Django shell、admin

    一.filter: 1.介绍: 写在模板中,属于Django的模板语言. 可以修改模板中的变量,从而显示不同的内容 2.使用: {{ value | filter }},且过滤器可以嵌套使用 < ...

  5. 42.OC中instancetype与id的区别

    区别: 在ARC(Auto Reference Count)环境下: instancetype用来在编译期确定实例的类型,而使用id的话,编译器不检查类型,运行时检查类型 在MRC(Manual Re ...

  6. 基础知识之nginx重写规则

    nginx重写规则 nginx rewrite 正则表达式匹配 大小写匹配 ~ 为区分大小写匹配 ~* 为不区分大小写匹配 !~和!~*分别为区分大小写不匹配及不区分大小写不匹配 文件及目录匹配 -f ...

  7. 消除flex-wrap之后每个item上下的距离

    设置flex-wrap后,每个item上下都会有距离.更改父元素的高度,就可以删除这些距离. 更改后:

  8. Le Chapitre VII

    Le cinquième jour, toujours grâce au mouton, ce secrèt de la vie du petit prince me fut révélé. Il m ...

  9. Educational Codeforces Round 60 C 思维 + 二分

    https://codeforces.com/contest/1117/problem/C 题意 在一个二维坐标轴上给你一个起点一个终点(x,y<=1e9),然后给你一串字符串代表每一秒的风向, ...

  10. 使用Docker镜像

    1     使用Docker镜像 1.1   获取镜像 命令格式:docker pull NAME[:TAG] NAME为镜像仓库的名称 TAG为镜像的标签(表示版本号) 描述一个镜像需要包括:名称+ ...