using System.Globalization; using System.Windows.Data; namespace Melskin.Converters.Internal { internal class ProgressToAngleConverter : IMultiValueConverter { public readonly static ProgressToAngleConverter Instance = new ProgressToAngleConverter(); public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { // 防御性检查:检查 UnsetValue 或 Null if (values == null || values.Length < 2 || values[0] == System.Windows.DependencyProperty.UnsetValue || values[0] == null || values[1] == System.Windows.DependencyProperty.UnsetValue || values[1] == null) { return System.Windows.Media.Geometry.Empty; } double value = System.Convert.ToDouble(values[0]); double max = System.Convert.ToDouble(values[1]); if (max <= 0) return System.Windows.Media.Geometry.Empty; // 确保百分比在 0-0.9999 之间 double percent = (value / max) <= 0 ? 0 : (value / max) >= 1 ? 0.9999 : value / max; double angle = percent * 360; double size = 100; double stroke = 10; double center = size / 2; double radius = (size - stroke) / 2; // 半径 45 double rad = (angle - 90) * Math.PI / 180; double x = center + radius * Math.Cos(rad); double y = center + radius * Math.Sin(rad); bool isLargeArc = angle > 180; Point startPoint = new Point(center, center - radius); Point endPoint = new Point(x, y); PathFigure figure = new PathFigure { StartPoint = startPoint, IsClosed = false }; figure.Segments.Add(new ArcSegment( endPoint, new Size(radius, radius), 0, isLargeArc, SweepDirection.Clockwise, true)); return new PathGeometry(new[] { figure }); } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } }