WPF 斜角border
最近看了一些科技感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的更多相关文章
- WPF 通过Border来画边框
WPF有自己的表格控件DataGrid.ListBox等,如果只是简单的需求,可以通过Border控件来画边框. 比如我们需要给上面的控件加上边框. <Window x:Class=" ...
- WPF 采用Border创建圆角
通过设置可以创建圆角border的CornerRadius属性其边框呈现圆角样式 代码: <Border Height="50" Background="Red&q ...
- WPF使用border画框
以前的界面中使用的框大都是由美工做好的,但是这样就遇到几个问题: 框只是换一个颜色,就需要多做出一张图,资源包中也要多一个图片资源: 文字的数量会改变,用一张固定的图进行拉伸,边角处会变得越来越不尽如 ...
- WPF参考
web 调用本地exe 程序,传入参数https://www.cnblogs.com/anjou/p/10045177.html WPF常用控件样式https://www.cnblogs.com/s0 ...
- WPF绘制自定义窗口
原文:WPF绘制自定义窗口 WPF是制作界面的一大利器,下面就用WPF模拟一下360的软件管理界面,360软件管理界面如下: 界面不难,主要有如下几个要素: 窗体的圆角 自定义标题栏及按钮 自定义状态 ...
- WPF学习:3.Border & Brush
上一章<WPF学习:2.Layout-Panels-Countainers>主要介绍了布局,容器和面板.这一章主要开始介绍Border(边界)和Brush(画刷). 代码地址:http:/ ...
- 【C#】WPF的xaml中定义的Trigger为什么有时候会不管用,如Border的MouseOver之类的
原文:[C#]WPF的xaml中定义的Trigger为什么有时候会不管用,如Border的MouseOver之类的 初学WPF,知道一些控件可以通过定义Style的Trigger改变要显示的样式,但是 ...
- WPF入门教程系列十——布局之Border与ViewBox(五)
九. Border Border 是一个装饰的控件,此控件绘制边框及背景,在 Border 中只能有一个子控件,若要显示多个子控件,需要将一个附加的 Panel 控件放置在父 Border 中.然后可 ...
- WPF控件---Border应用
内容模型:Border 只能具有一个子元素.若要显示多个子元素, 需要将一个容器元素放置在父元素Border中. <Grid> <Border BorderBrush="B ...
随机推荐
- windows 下设置nginx负载均衡
#user nobody; worker_processes ; #error_log logs/error.log; #error_log logs/error.log notice; #error ...
- CRC-32的原理和实现
/* crc32.c -- compute the CRC-32 of a data stream * Copyright (C) 1995-2002 Mark Adler * For conditi ...
- [网络]10M、100M、1000M网线的水晶头接法
在网络维护过程中经常要自己制作网线,水晶头理论上是这样接的: 10M和100M和1000M以太网在使用网线时,对网线各自有不同的要求. 10M和100M在目前来说,连接网络的时候,只用到两对线来传输网 ...
- HDU 6185(打表代码
/** @xigua */ #include <cstdio> #include <cmath> #include <iostream> #include < ...
- centos7修改root根目录
1.拷贝/root 原目录的东西到新目录中(包括.xxx文件) /abc 2.修改配置文件 vi /etc/passwd root:x:0:0:root:/root:/bin/bash ==> ...
- 2018.12.22 bzoj3277: 串(后缀自动机+启发式合并)
传送门 跟这道题是一模一样的. 于是本蒟蒻又写了一遍10min1A庆祝 代码: #include<bits/stdc++.h> #define ri register int using ...
- 2018.12.15 spoj1812 Longest Common Substring(后缀自动机)
传送门 后缀自动机模板题. 题意简述:求两个字串的最长公共子串长度. 对其中一个构建后缀自动机,用另外一个在上面跑即可. 代码: #include<bits/stdc++.h> #defi ...
- this指针和const成员函数
1.this指针 1)this指针是成员函数的隐式参数,成员函数通过this指针来访问调用它自己的那个对象,成员函数对各成员的访问均通过this进行 2)当某个对象调用它的成员函数时,编译器会把这个对 ...
- s4-3 CSMA
载波侦听多路访问协议 CSMA:Carrier Sense Multiple Access 特点:"先听后发" 改进ALOHA协议的侦听/发送策略 分类 非持续式 持 ...
- UVaLive 3641 Leonardo's Notebook (置换)
题意:给定一个置换 B 问是否则存在一个置换 A ,使用 A^2 = B. 析:可以自己画一画,假设 A = (a1, a2, a3)(b1, b2, b3, b4),那么 A^2 = (a1, a2 ...