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