using System; using System.ComponentModel; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; namespace MegaRobo.C00225155App.MenuViews.Bottles { /// /// 预估CT指示器控件 - 显示环形进度条和中心CT值 /// [TemplatePart(Name = "PART_BackgroundPath", Type = typeof(Path))] [TemplatePart(Name = "PART_ProgressPath", Type = typeof(Path))] [TemplatePart(Name = "PART_CTText", Type = typeof(TextBlock))] public class CTIndicator : Control { static CTIndicator() { DefaultStyleKeyProperty.OverrideMetadata(typeof(CTIndicator), new FrameworkPropertyMetadata(typeof(CTIndicator))); } #region 依赖属性 /// /// 进度值 (0.0 - 1.0) /// public double Progress { get => (double)GetValue(ProgressProperty); set => SetValue(ProgressProperty, value); } public static readonly DependencyProperty ProgressProperty = DependencyProperty.Register("Progress", typeof(double), typeof(CTIndicator), new PropertyMetadata(0.0, OnProgressChanged)); /// /// CT值文本 /// public string CTValue { get => (string)GetValue(CTValueProperty); set => SetValue(CTValueProperty, value); } public static readonly DependencyProperty CTValueProperty = DependencyProperty.Register("CTValue", typeof(string), typeof(CTIndicator), new PropertyMetadata("0min")); /// /// 进度条颜色 /// public Brush ProgressColor { get => (Brush)GetValue(ProgressColorProperty); set => SetValue(ProgressColorProperty, value); } public static readonly DependencyProperty ProgressColorProperty = DependencyProperty.Register("ProgressColor", typeof(Brush), typeof(CTIndicator), new PropertyMetadata(Brushes.Green)); /// /// 背景环颜色 /// public Brush BackgroundColor { get => (Brush)GetValue(BackgroundColorProperty); set => SetValue(BackgroundColorProperty, value); } public static readonly DependencyProperty BackgroundColorProperty = DependencyProperty.Register("BackgroundColor", typeof(Brush), typeof(CTIndicator), new PropertyMetadata(Brushes.LightGray)); /// /// 文本颜色 /// public Brush TextColor { get => (Brush)GetValue(TextColorProperty); set => SetValue(TextColorProperty, value); } public static readonly DependencyProperty TextColorProperty = DependencyProperty.Register("TextColor", typeof(Brush), typeof(CTIndicator), new PropertyMetadata(Brushes.Black)); /// /// 环厚度 /// public double RingThickness { get => (double)GetValue(RingThicknessProperty); set => SetValue(RingThicknessProperty, value); } public static readonly DependencyProperty RingThicknessProperty = DependencyProperty.Register("RingThickness", typeof(double), typeof(CTIndicator), new PropertyMetadata(6.0)); /// /// 字体大小 /// public double CTFontSize { get => (double)GetValue(CTFontSizeProperty); set => SetValue(CTFontSizeProperty, value); } public static readonly DependencyProperty CTFontSizeProperty = DependencyProperty.Register("CTFontSize", typeof(double), typeof(CTIndicator), new PropertyMetadata(10.0)); #endregion #region 模板部件 private Path _backgroundPath; private Path _progressPath; private TextBlock _ctText; public void ForceRefresh() { UpdateProgressPath(); UpdateCTValueText(); // 新增:显式更新CTValue文本 } public override void OnApplyTemplate() { base.OnApplyTemplate(); _backgroundPath = GetTemplateChild("PART_BackgroundPath") as Path; _progressPath = GetTemplateChild("PART_ProgressPath") as Path; _ctText = GetTemplateChild("PART_CTText") as TextBlock; UpdateProgressPath(); UpdateCTValueText(); SizeChanged += OnSizeChanged; } #endregion #region 事件处理 private static void OnProgressChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var indicator = (CTIndicator)d; indicator.UpdateProgressPath(); } private void OnSizeChanged(object sender, SizeChangedEventArgs e) { UpdateProgressPath(); } #endregion #region 绘制逻辑 private void UpdateProgressPath() { if (_backgroundPath == null || _progressPath == null || _ctText == null) return; double width = ActualWidth > 0 ? ActualWidth : 33; double height = ActualHeight > 0 ? ActualHeight : 33; double ringThickness = RingThickness; double radius = Math.Max(0, Math.Min(width, height) / 2 - ringThickness / 2); double centerX = width / 2; double centerY = height / 2; // 更新背景环 _backgroundPath.StrokeThickness = ringThickness; _backgroundPath.Data = new EllipseGeometry { Center = new Point(centerX, centerY), RadiusX = radius, RadiusY = radius }; // 更新进度环 _progressPath.StrokeThickness = ringThickness; _progressPath.Stroke = ProgressColor; double angle = Progress * 360; bool isLargeArc = angle > 180; // 特殊处理0%和100%的情况 if (Progress >= 1.0) { _progressPath.Data = new EllipseGeometry { Center = new Point(centerX, centerY), RadiusX = radius, RadiusY = radius }; } else if (Progress <= 0.0) { // 创建不可见的微小线段 var geometry = new LineGeometry( new Point(centerX, centerY - radius), new Point(centerX, centerY - radius + 0.01)); _progressPath.Data = geometry; } else { Point endPoint = new Point( centerX + radius * Math.Sin(angle * Math.PI / 180), centerY - radius * Math.Cos(angle * Math.PI / 180) ); PathGeometry geometry = new PathGeometry(); PathFigure figure = new PathFigure { StartPoint = new Point(centerX, centerY - radius), IsClosed = false }; figure.Segments.Add(new ArcSegment { Point = endPoint, Size = new Size(radius, radius), IsLargeArc = isLargeArc, SweepDirection = SweepDirection.Clockwise, RotationAngle = 0 }); geometry.Figures.Add(figure); _progressPath.Data = geometry; } // 更新文本 _ctText.Text = CTValue; _ctText.FontSize = CTFontSize; _ctText.Foreground = TextColor; } private void UpdateCTValueText() { if (_ctText == null) return; _ctText.Text = CTValue; // 确保文本与依赖属性同步 } #endregion } }