[WPF] 继承Shape实现弧形、扇形控件
属性:
RadianStart:开始弧度,默认值-90,即从最上面开始顺时针画。
Radian:弧度,默认值0。
IsSector:是否扇形,默认值False,默认是弧形。
IsAutoAnimate:是否自动使用动画,默认值False,若为True,则RadianStart和Radian的值变化时,自动使用动画。
效果展示:
核心代码:
private Geometry DrawGeometry() { // 圆心 var cx = RenderSize.Width / 2; var cy = RenderSize.Height / 2; // 若控件大小为0,或弧度为0,则不绘制 if (cx == 0 || cy == 0 || Radian == 0) return Geometry.Empty; var r = Math.Min(cx, cy) - StrokeThickness / 2; // 半径 var d = 2 * r; // 直径 // 若弧度恰好为一个整圆,则绘制两个半圆 if (Radian % 360 == 0) { // 计算开始、结束弧度坐标点 var s = CoordMap(cx, cy, r, 0); var e = CoordMap(cx, cy, r, 180); var desc = $"M0 0 M{d} {d} M{s.X} {s.Y} A{r} {r} 0 0 1 {e.X} {e.Y} A{r} {r} 0 0 1 {s.X} {s.Y}"; var geometry = Geometry.Parse(desc); geometry.Freeze(); return geometry; } else { // 计算开始、结束弧度坐标点 var s = CoordMap(cx, cy, r, RadianStart); var e = CoordMap(cx, cy, r, RadianStart + Radian); // 判断是否为大圆 var lenghty = Radian % 360 > 180 ? 1 : 0; string desc = null; // 判断是否扇形 if (IsSector) desc = $"M0 0 M{d} {d} M{cx} {cy} L{s.X} {s.Y} A{r} {r} 0 {lenghty} 1 {e.X} {e.Y} Z"; else desc = $"M0 0 M{d} {d} M{s.X} {s.Y} A{r} {r} 0 {lenghty} 1 {e.X} {e.Y}"; var geometry = Geometry.Parse(desc); geometry.Freeze(); return geometry; } } /// <summary> /// 极坐标转换 /// </summary> /// <param name="x">圆心x</param> /// <param name="y">圆心y</param> /// <param name="r">半径</param> /// <param name="a">弧度</param> /// <returns></returns> private Point CoordMap(Double x, Double y, Double r, Double a) { var ta = (360 - a) * Math.PI / 180; var tx = r * Math.Cos(ta); // 角度邻边 var ty = r * Math.Sin(ta); // 角度的对边 return new Point(x + tx, y - ty); }
更多详情,请查看PP.WPF控件库。