using System; using System.Collections.Generic; using System.ComponentModel; using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace WpfApp.src.components { /// /// SensorChart.xaml 的交互逻辑 /// public partial class SensorChart : UserControl, INotifyPropertyChanged { public SensorChart() { InitializeComponent(); DataContext = this; // 设置默认值 SensorName = "传感器"; HeaderBackground = new SolidColorBrush(Color.FromRgb(230, 243, 255)); // #E6F3FF Value = 0; RedLineValues = new List(); } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } #region 依赖属性 // 传感器名称 public static readonly DependencyProperty SensorNameProperty = DependencyProperty.Register("SensorName", typeof(string), typeof(SensorChart), new PropertyMetadata("传感器", OnSensorNameChanged)); public string SensorName { get { return (string)GetValue(SensorNameProperty); } set { SetValue(SensorNameProperty, value); } } private static void OnSensorNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var control = d as SensorChart; control?.OnPropertyChanged(nameof(SensorName)); } // 标题背景色 public static readonly DependencyProperty HeaderBackgroundProperty = DependencyProperty.Register("HeaderBackground", typeof(Brush), typeof(SensorChart), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(230, 243, 255)), OnHeaderBackgroundChanged)); public Brush HeaderBackground { get { return (Brush)GetValue(HeaderBackgroundProperty); } set { SetValue(HeaderBackgroundProperty, value); } } private static void OnHeaderBackgroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var control = d as SensorChart; control?.OnPropertyChanged(nameof(HeaderBackground)); } // 数值 public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(SensorChart), new PropertyMetadata(0.0, OnValueChanged)); public double Value { get { return (double)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var control = d as SensorChart; control?.UpdateBarPosition(); } // 红线数值列表 public static readonly DependencyProperty RedLineValuesProperty = DependencyProperty.Register("RedLineValues", typeof(List), typeof(SensorChart), new PropertyMetadata(new List(), OnRedLineValuesChanged)); public List RedLineValues { get { return (List)GetValue(RedLineValuesProperty); } set { SetValue(RedLineValuesProperty, value); } } private static void OnRedLineValuesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var control = d as SensorChart; control?.UpdateRedLinePositions(); } #endregion #region 计算属性 private double _barTop; public double BarTop { get { return _barTop; } private set { _barTop = value; OnPropertyChanged(nameof(BarTop)); } } private double _barHeight; public double BarHeight { get { return _barHeight; } private set { _barHeight = value; OnPropertyChanged(nameof(BarHeight)); } } private List _redLinePositions = new List(); public List RedLinePositions { get { return _redLinePositions; } private set { _redLinePositions = value; OnPropertyChanged(nameof(RedLinePositions)); } } #endregion #region 私有方法 /// /// 将数值转换为Y坐标位置 /// 刻度范围:40 到 -40,对应Y坐标:20 到 420 /// /// 数值 /// Y坐标 private double ValueToY(double value) { // 限制数值范围 value = Math.Max(-40, Math.Min(40, value)); // 线性映射:40对应Y=20,-40对应Y=420 // Y = 220 - value * 5 return 220 - value * 5; } /// /// 更新柱状图位置 /// private void UpdateBarPosition() { if (Value >= 0) { // 正值:从0线向上 BarTop = ValueToY(Value); BarHeight = ValueToY(0) - ValueToY(Value); } else { // 负值:从0线向下 BarTop = ValueToY(0); BarHeight = ValueToY(Value) - ValueToY(0); } } /// /// 更新红线位置 /// private void UpdateRedLinePositions() { var positions = new List(); if (RedLineValues != null) { foreach (var value in RedLineValues) { positions.Add(ValueToY(value)); } } RedLinePositions = positions; } #endregion #region 公共方法 /// /// 设置传感器数据 /// /// 传感器名称 /// 数值 /// 红线数值列表 /// 标题背景色 public void SetSensorData(string name, double value, List redLines = null, Color? headerColor = null) { SensorName = name; Value = value; if (redLines != null) { RedLineValues = new List(redLines); } if (headerColor.HasValue) { HeaderBackground = new SolidColorBrush(headerColor.Value); } } /// /// 添加红线 /// /// 红线数值 public void AddRedLine(double value) { var lines = new List(RedLineValues) { value }; RedLineValues = lines; } /// /// 清除所有红线 /// public void ClearRedLines() { RedLineValues = new List(); } #endregion } }