WpfApp/src/components/SensorChart.xaml.cs

243 lines
7.3 KiB
C#
Raw Normal View History

2025-10-10 15:58:01 +08:00
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace WpfApp.src.components
{
/// <summary>
/// SensorChart.xaml 的交互逻辑
/// </summary>
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<double>();
}
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<double>), typeof(SensorChart),
new PropertyMetadata(new List<double>(), OnRedLineValuesChanged));
public List<double> RedLineValues
{
get { return (List<double>)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<double> _redLinePositions = new List<double>();
public List<double> RedLinePositions
{
get { return _redLinePositions; }
private set
{
_redLinePositions = value;
OnPropertyChanged(nameof(RedLinePositions));
}
}
#endregion
#region
/// <summary>
/// 将数值转换为Y坐标位置
/// 刻度范围40 到 -40对应Y坐标20 到 420
/// </summary>
/// <param name="value">数值</param>
/// <returns>Y坐标</returns>
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;
}
/// <summary>
/// 更新柱状图位置
/// </summary>
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);
}
}
/// <summary>
/// 更新红线位置
/// </summary>
private void UpdateRedLinePositions()
{
var positions = new List<double>();
if (RedLineValues != null)
{
foreach (var value in RedLineValues)
{
positions.Add(ValueToY(value));
}
}
RedLinePositions = positions;
}
#endregion
#region
/// <summary>
/// 设置传感器数据
/// </summary>
/// <param name="name">传感器名称</param>
/// <param name="value">数值</param>
/// <param name="redLines">红线数值列表</param>
/// <param name="headerColor">标题背景色</param>
public void SetSensorData(string name, double value, List<double> redLines = null, Color? headerColor = null)
{
SensorName = name;
Value = value;
if (redLines != null)
{
RedLineValues = new List<double>(redLines);
}
if (headerColor.HasValue)
{
HeaderBackground = new SolidColorBrush(headerColor.Value);
}
}
/// <summary>
/// 添加红线
/// </summary>
/// <param name="value">红线数值</param>
public void AddRedLine(double value)
{
var lines = new List<double>(RedLineValues) { value };
RedLineValues = lines;
}
/// <summary>
/// 清除所有红线
/// </summary>
public void ClearRedLines()
{
RedLineValues = new List<double>();
}
#endregion
}
}