1. 程式人生 > 其它 >[WPF] 繼承Shape實現弧形、扇形控制元件

[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控制元件庫。