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
}
}