节点
This commit is contained in:
parent
18a63a1c1d
commit
0a2798497f
|
|
@ -4,442 +4,296 @@ using LiveCharts.Wpf;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Media;
|
||||||
using System.Windows.Navigation;
|
using System.Windows.Navigation;
|
||||||
using WpfApp.src.components;
|
using WpfApp.src.components;
|
||||||
|
using WpfApp.src.config;
|
||||||
using WpfApp.src.view;
|
using WpfApp.src.view;
|
||||||
|
using WpfApp.Utils;
|
||||||
|
|
||||||
|
|
||||||
namespace WpfApp
|
namespace WpfApp;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for MainWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class MainWindow : Window
|
||||||
{
|
{
|
||||||
/// <summary>
|
private readonly LogService log;
|
||||||
/// Interaction logic for MainWindow.xaml
|
private readonly DatabaseService db;
|
||||||
/// </summary>
|
private readonly EventService<GeneralEventArgs> even;
|
||||||
public partial class MainWindow : Window
|
|
||||||
|
public MainWindow(LogService logService, DatabaseService databaseService, EventService<GeneralEventArgs> eventService)
|
||||||
{
|
{
|
||||||
private readonly LogService log;
|
InitializeComponent();
|
||||||
private readonly DatabaseService db;
|
|
||||||
private readonly EventService<GeneralEventArgs> even;
|
|
||||||
|
|
||||||
public MainWindow(LogService logService, DatabaseService databaseService, EventService<GeneralEventArgs> eventService)
|
log = logService;
|
||||||
|
db = databaseService;
|
||||||
|
even = eventService;
|
||||||
|
|
||||||
|
// 记录窗口初始化日志
|
||||||
|
log.Info("MainWindow", "主窗口已通过依赖注入初始化");
|
||||||
|
log.Info("窗体启动");
|
||||||
|
even.AddEventHandler("GeneralEvent", (m, d) =>
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
log.Info($"接收到事件:{d.Data}");
|
||||||
|
});
|
||||||
|
SetWindowTitle("FMSDGAUGE");
|
||||||
|
|
||||||
log = logService;
|
var labels = new[] { "13:27 23", "13:27 45", "13:27 49", "13:27 50", "13:27 55" };
|
||||||
db = databaseService;
|
|
||||||
even = eventService;
|
|
||||||
|
|
||||||
// 记录窗口初始化日志
|
var config1 = new ChartConfig
|
||||||
log.Info("MainWindow", "主窗口已通过依赖注入初始化");
|
|
||||||
log.Info("窗体启动");
|
|
||||||
even.AddEventHandler("GeneralEvent", (m, d) =>
|
|
||||||
{
|
|
||||||
log.Info($"接收到事件:{d.Data}");
|
|
||||||
});
|
|
||||||
|
|
||||||
#region 曲线测试数据
|
|
||||||
SetWindowTitle("FMSDGAUGE");
|
|
||||||
|
|
||||||
// 传感器1
|
|
||||||
// 初始化Series
|
|
||||||
myChart.Series = new SeriesCollection
|
|
||||||
{
|
|
||||||
// 柱状图
|
|
||||||
new ColumnSeries
|
|
||||||
{
|
|
||||||
Title = "柱状数据",
|
|
||||||
Values = new ChartValues<double> { 20, 10, 12, 5, 9 }
|
|
||||||
},
|
|
||||||
// 标准1
|
|
||||||
new LineSeries
|
|
||||||
{
|
|
||||||
Title = "标准1",
|
|
||||||
Values = new ChartValues<double> { 5, 5, 5, 5, 5 },
|
|
||||||
DataLabels = true,
|
|
||||||
LabelPoint = value => value.Y.ToString("0.##") + " Hz",
|
|
||||||
StrokeThickness = 2,
|
|
||||||
Fill = System.Windows.Media.Brushes.Transparent
|
|
||||||
},
|
|
||||||
// 标准2
|
|
||||||
new LineSeries
|
|
||||||
{
|
|
||||||
Title = "标准2",
|
|
||||||
Values = new ChartValues<double> { 10, 10, 10, 10, 10 },
|
|
||||||
DataLabels = true,
|
|
||||||
LabelPoint = value => value.Y.ToString("0.##") + " Hz",
|
|
||||||
//Foreground = System.Windows.Media.Brushes.Blue,// 标签颜色
|
|
||||||
//FontSize = 14,// 字体大小
|
|
||||||
// StrokeThickness = 2, // 线条粗细
|
|
||||||
StrokeThickness = 2,
|
|
||||||
Stroke = System.Windows.Media.Brushes.Green,
|
|
||||||
Fill = System.Windows.Media.Brushes.Transparent
|
|
||||||
},
|
|
||||||
// 标准3
|
|
||||||
new LineSeries
|
|
||||||
{
|
|
||||||
Title = "标准3",
|
|
||||||
Values = new ChartValues<double> { 30, 30, 30, 30, 30 },
|
|
||||||
DataLabels = true,
|
|
||||||
LabelPoint = value => value.Y.ToString("0.##") + " Hz",
|
|
||||||
StrokeThickness = 2,
|
|
||||||
Stroke = System.Windows.Media.Brushes.Red,
|
|
||||||
Fill = System.Windows.Media.Brushes.Transparent
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 设置X轴标签
|
|
||||||
myChart.AxisX.Add(new Axis
|
|
||||||
{
|
|
||||||
Title = "",
|
|
||||||
Labels = new[] { "13:27 23", "13:27 45", "13:27 49", "13:27 50", "13:27 55" }
|
|
||||||
});
|
|
||||||
|
|
||||||
// 设置Y轴
|
|
||||||
myChart.AxisY.Add(new Axis
|
|
||||||
{
|
|
||||||
Title = ""
|
|
||||||
});
|
|
||||||
|
|
||||||
// 传感器2
|
|
||||||
// 初始化Series
|
|
||||||
myChart1.Series = new SeriesCollection
|
|
||||||
{
|
|
||||||
// 柱状图
|
|
||||||
new ColumnSeries
|
|
||||||
{
|
|
||||||
Title = "柱状数据",
|
|
||||||
Values = new ChartValues<double> { 20, 10, 12, 5, 9 }
|
|
||||||
},
|
|
||||||
// 标准1
|
|
||||||
new LineSeries
|
|
||||||
{
|
|
||||||
Title = "标准1",
|
|
||||||
Values = new ChartValues<double> { 5, 5, 5, 5, 5 },
|
|
||||||
StrokeThickness = 2,
|
|
||||||
Fill = System.Windows.Media.Brushes.Transparent
|
|
||||||
},
|
|
||||||
// 标准2
|
|
||||||
new LineSeries
|
|
||||||
{
|
|
||||||
Title = "标准2",
|
|
||||||
Values = new ChartValues<double> { 10, 10, 10, 10, 10 },
|
|
||||||
StrokeThickness = 2,
|
|
||||||
Stroke = System.Windows.Media.Brushes.Green,
|
|
||||||
Fill = System.Windows.Media.Brushes.Transparent
|
|
||||||
},
|
|
||||||
// 标准3
|
|
||||||
new LineSeries
|
|
||||||
{
|
|
||||||
Title = "标准3",
|
|
||||||
Values = new ChartValues<double> { 30, 30, 30, 30, 30 },
|
|
||||||
StrokeThickness = 2,
|
|
||||||
Stroke = System.Windows.Media.Brushes.Red,
|
|
||||||
Fill = System.Windows.Media.Brushes.Transparent
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 设置X轴标签
|
|
||||||
myChart1.AxisX.Add(new Axis
|
|
||||||
{
|
|
||||||
Title = "",
|
|
||||||
Labels = new[] { "13:27 23", "13:27 45", "13:27 49", "13:27 50", "13:27 55" }
|
|
||||||
});
|
|
||||||
|
|
||||||
// 设置Y轴
|
|
||||||
myChart1.AxisY.Add(new Axis
|
|
||||||
{
|
|
||||||
Title = ""
|
|
||||||
});
|
|
||||||
|
|
||||||
// 传感器3
|
|
||||||
// 初始化Series
|
|
||||||
myChart2.Series = new SeriesCollection
|
|
||||||
{
|
|
||||||
// 柱状图
|
|
||||||
new ColumnSeries
|
|
||||||
{
|
|
||||||
Title = "柱状数据",
|
|
||||||
Values = new ChartValues<double> { 20, 10, 12, 5, 9 }
|
|
||||||
},
|
|
||||||
// 标准1
|
|
||||||
new LineSeries
|
|
||||||
{
|
|
||||||
Title = "标准1",
|
|
||||||
Values = new ChartValues<double> { 5, 5, 5, 5, 5 },
|
|
||||||
StrokeThickness = 2,
|
|
||||||
Fill = System.Windows.Media.Brushes.Transparent
|
|
||||||
},
|
|
||||||
// 标准2
|
|
||||||
new LineSeries
|
|
||||||
{
|
|
||||||
Title = "标准2",
|
|
||||||
Values = new ChartValues<double> { 10, 10, 10, 10, 10 },
|
|
||||||
StrokeThickness = 2,
|
|
||||||
Stroke = System.Windows.Media.Brushes.Green,
|
|
||||||
Fill = System.Windows.Media.Brushes.Transparent
|
|
||||||
},
|
|
||||||
// 标准3
|
|
||||||
new LineSeries
|
|
||||||
{
|
|
||||||
Title = "标准3",
|
|
||||||
Values = new ChartValues<double> { 30, 30, 30, 30, 30 },
|
|
||||||
StrokeThickness = 2,
|
|
||||||
Stroke = System.Windows.Media.Brushes.Red,
|
|
||||||
Fill = System.Windows.Media.Brushes.Transparent
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 设置X轴标签
|
|
||||||
myChart2.AxisX.Add(new Axis
|
|
||||||
{
|
|
||||||
Title = "",
|
|
||||||
Labels = new[] { "13:27 23", "13:27 45", "13:27 49", "13:27 50", "13:27 55" }
|
|
||||||
});
|
|
||||||
|
|
||||||
// 设置Y轴
|
|
||||||
myChart2.AxisY.Add(new Axis
|
|
||||||
{
|
|
||||||
Title = ""
|
|
||||||
});
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Button_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
{
|
||||||
SqlSugarScope scope = db.GetScope("LocalData");
|
ColumnData = new List<double> { 20, 10, 12, 5, 9 },
|
||||||
scope.guokeCheckToCreate<aaa>();//检查并创建表
|
Labels = new List<string>(labels),
|
||||||
even.TriggerEvent("GeneralEvent", this, new GeneralEventArgs("测试", 1));
|
LineConfigs = new List<LineConfig>
|
||||||
}
|
|
||||||
public class aaa : BaseTableModel
|
|
||||||
{
|
{
|
||||||
|
new LineConfig { Title = "标准1", Values = new List<double> { 5,5,5,5,5 }, Stroke = Brushes.Blue },
|
||||||
|
new LineConfig { Title = "标准2", Values = new List<double> { 10,10,10,10,10 }, Stroke = Brushes.Green },
|
||||||
|
new LineConfig { Title = "标准3", Values = new List<double> { 30,30,30,30,30 }, Stroke = Brushes.Red, Unit = "A" }
|
||||||
}
|
}
|
||||||
/// <summary>
|
};
|
||||||
/// 设置窗体标题的函数
|
InitChart.InitCartesianChart(myChart, config1);
|
||||||
/// </summary>
|
InitChart.InitCartesianChart(myChart1, config1);
|
||||||
/// <param name="newTitle"></param>
|
InitChart.InitCartesianChart(myChart2, config1);
|
||||||
public void SetWindowTitle(string newTitle)
|
|
||||||
{
|
|
||||||
this.Title = newTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region 菜单点击按钮
|
|
||||||
// 在 MainWindow 内部
|
|
||||||
/// <summary>
|
|
||||||
/// 按钮点击触发文件页面
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="e"></param>
|
|
||||||
private void OnFilePageButtonClick(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
FilePage filePage = new FilePage();
|
|
||||||
NavigationWindow navWin = new NavigationWindow();
|
|
||||||
|
|
||||||
navWin.Width = 810;
|
|
||||||
navWin.Height = 600;
|
|
||||||
navWin.ResizeMode = ResizeMode.NoResize;
|
|
||||||
navWin.Content = filePage;
|
|
||||||
navWin.ShowsNavigationUI = false;
|
|
||||||
navWin.Title = "记录列表";
|
|
||||||
|
|
||||||
|
|
||||||
// ✅ 新增:设定父窗口、样式与居中弹出
|
|
||||||
navWin.Owner = Application.Current.MainWindow; // 绑定主窗口
|
|
||||||
navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出
|
|
||||||
navWin.WindowStyle = WindowStyle.ToolWindow;
|
|
||||||
|
|
||||||
// ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口
|
|
||||||
navWin.ShowDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 按钮点击触发配置页面
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="e"></param>
|
|
||||||
private void OnConfigPageButtonClick(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
ConfigPage configPage = new ConfigPage();
|
|
||||||
NavigationWindow navWin = new NavigationWindow();
|
|
||||||
navWin.Content = configPage;
|
|
||||||
navWin.ShowsNavigationUI = false;
|
|
||||||
navWin.Width = 972;
|
|
||||||
navWin.Height = 648;
|
|
||||||
navWin.Title = "配置";
|
|
||||||
navWin.ResizeMode = ResizeMode.NoResize;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ✅ 新增:设定父窗口、样式与居中弹出
|
|
||||||
navWin.Owner = Application.Current.MainWindow; // 绑定主窗口
|
|
||||||
navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出
|
|
||||||
navWin.WindowStyle = WindowStyle.ToolWindow;
|
|
||||||
|
|
||||||
// ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口
|
|
||||||
navWin.ShowDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 按钮点击触发标准基准页面
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="e"></param>
|
|
||||||
private void OnStandardPageButtonClick(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
StandardPage standardPage = new StandardPage();
|
|
||||||
NavigationWindow navWin = new NavigationWindow();
|
|
||||||
navWin.Width = 972;
|
|
||||||
navWin.Height = 648;
|
|
||||||
//navWin.ResizeMode = ResizeMode.NoResize;
|
|
||||||
navWin.Content = standardPage;
|
|
||||||
navWin.ShowsNavigationUI = false;
|
|
||||||
navWin.Title = "主标定";
|
|
||||||
|
|
||||||
|
|
||||||
// ✅ 新增:设定父窗口、样式与居中弹出
|
|
||||||
navWin.Owner = Application.Current.MainWindow; // 绑定主窗口
|
|
||||||
navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出
|
|
||||||
navWin.WindowStyle = WindowStyle.ToolWindow;
|
|
||||||
|
|
||||||
// ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口
|
|
||||||
navWin.ShowDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 按钮点击触发Gauge页面
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="e"></param>
|
|
||||||
private void OnGaugePageButtonClick(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
GaugePage gaugePage = new GaugePage();
|
|
||||||
NavigationWindow navWin = new NavigationWindow();
|
|
||||||
navWin.Content = gaugePage;
|
|
||||||
navWin.ShowsNavigationUI = false;
|
|
||||||
navWin.Width = 1080;
|
|
||||||
navWin.Height = 720;
|
|
||||||
navWin.Title = "Gauge R&&R";
|
|
||||||
|
|
||||||
// ✅ 新增:设定父窗口、样式与居中弹出
|
|
||||||
navWin.Owner = Application.Current.MainWindow; // 绑定主窗口
|
|
||||||
navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出
|
|
||||||
navWin.WindowStyle = WindowStyle.ToolWindow;
|
|
||||||
|
|
||||||
// ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口
|
|
||||||
navWin.ShowDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 按钮点击触发CgCgk页面
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="e"></param>
|
|
||||||
private void OnCgCgkPageButtonClick(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
CgCgkPage cgCgkPage = new CgCgkPage();
|
|
||||||
NavigationWindow navWin = new NavigationWindow();
|
|
||||||
navWin.Content = cgCgkPage;
|
|
||||||
navWin.ShowsNavigationUI = false;
|
|
||||||
navWin.Title = "CgCgk";
|
|
||||||
|
|
||||||
|
|
||||||
// ✅ 新增:设定父窗口、样式与居中弹出
|
|
||||||
navWin.Owner = Application.Current.MainWindow; // 绑定主窗口
|
|
||||||
navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出
|
|
||||||
navWin.WindowStyle = WindowStyle.ToolWindow;
|
|
||||||
|
|
||||||
// ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口
|
|
||||||
navWin.ShowDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 按钮点击触发系统设置页面
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="e"></param>
|
|
||||||
private void OnSysSetPageButtonClick(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
SysSetPage sysSetPage = new SysSetPage();
|
|
||||||
NavigationWindow navWin = new NavigationWindow();
|
|
||||||
navWin.Width = 810;
|
|
||||||
navWin.Height = 600;
|
|
||||||
navWin.ResizeMode = ResizeMode.NoResize;
|
|
||||||
navWin.Content = sysSetPage;
|
|
||||||
navWin.ShowsNavigationUI = false;
|
|
||||||
navWin.Title = "系统设置";
|
|
||||||
|
|
||||||
|
|
||||||
// ✅ 新增:设定父窗口、样式与居中弹出
|
|
||||||
navWin.Owner = Application.Current.MainWindow; // 绑定主窗口
|
|
||||||
navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出
|
|
||||||
navWin.WindowStyle = WindowStyle.ToolWindow;
|
|
||||||
|
|
||||||
// ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口
|
|
||||||
navWin.ShowDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 关闭和测试按钮
|
|
||||||
/// <summary>
|
|
||||||
/// 按钮点击触发关闭页面
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="e"></param>
|
|
||||||
private void OnCloseMainWindowButtonClick(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
this.Close();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 测试按钮
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="e"></param>
|
|
||||||
private void OnDemoButtonClick(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
//LineBarChartDemo lineBarChartDemo = new LineBarChartDemo();
|
|
||||||
//lineBarChartDemo.Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 等级选择下拉框变化事件处理
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="e"></param>
|
|
||||||
private void LevelComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
||||||
{
|
|
||||||
if (sender is ComboBox comboBox && comboBox.SelectedItem is ComboBoxItem selectedItem)
|
|
||||||
{
|
|
||||||
// 根据选择的Tag确定等级
|
|
||||||
SensorLevel selectedLevel = SensorLevel.Medium; // 默认值
|
|
||||||
switch (selectedItem.Tag?.ToString())
|
|
||||||
{
|
|
||||||
case "Low":
|
|
||||||
selectedLevel = SensorLevel.Low;
|
|
||||||
break;
|
|
||||||
case "Medium":
|
|
||||||
selectedLevel = SensorLevel.Medium;
|
|
||||||
break;
|
|
||||||
case "High":
|
|
||||||
selectedLevel = SensorLevel.High;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新所有传感器图表的等级
|
|
||||||
Sensor1.Level = selectedLevel;
|
|
||||||
Sensor2.Level = selectedLevel;
|
|
||||||
Sensor3.Level = selectedLevel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Button_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
SqlSugarScope scope = db.GetScope("LocalData");
|
||||||
|
scope.guokeCheckToCreate<aaa>();//检查并创建表
|
||||||
|
even.TriggerEvent("GeneralEvent", this, new GeneralEventArgs("测试", 1));
|
||||||
|
}
|
||||||
|
public class aaa : BaseTableModel
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 设置窗体标题的函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="newTitle"></param>
|
||||||
|
public void SetWindowTitle(string newTitle)
|
||||||
|
{
|
||||||
|
this.Title = newTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region 菜单点击按钮
|
||||||
|
// 在 MainWindow 内部
|
||||||
|
/// <summary>
|
||||||
|
/// 按钮点击触发文件页面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void OnFilePageButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
FilePage filePage = new FilePage();
|
||||||
|
NavigationWindow navWin = new NavigationWindow();
|
||||||
|
|
||||||
|
navWin.Width = 810;
|
||||||
|
navWin.Height = 600;
|
||||||
|
navWin.ResizeMode = ResizeMode.NoResize;
|
||||||
|
navWin.Content = filePage;
|
||||||
|
navWin.ShowsNavigationUI = false;
|
||||||
|
navWin.Title = "记录列表";
|
||||||
|
|
||||||
|
|
||||||
|
// ✅ 新增:设定父窗口、样式与居中弹出
|
||||||
|
navWin.Owner = Application.Current.MainWindow; // 绑定主窗口
|
||||||
|
navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出
|
||||||
|
navWin.WindowStyle = WindowStyle.ToolWindow;
|
||||||
|
|
||||||
|
// ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口
|
||||||
|
navWin.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 按钮点击触发配置页面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void OnConfigPageButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
ConfigPage configPage = new ConfigPage();
|
||||||
|
NavigationWindow navWin = new NavigationWindow();
|
||||||
|
navWin.Content = configPage;
|
||||||
|
navWin.ShowsNavigationUI = false;
|
||||||
|
navWin.Width = 972;
|
||||||
|
navWin.Height = 648;
|
||||||
|
navWin.Title = "配置";
|
||||||
|
navWin.ResizeMode = ResizeMode.NoResize;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ✅ 新增:设定父窗口、样式与居中弹出
|
||||||
|
navWin.Owner = Application.Current.MainWindow; // 绑定主窗口
|
||||||
|
navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出
|
||||||
|
navWin.WindowStyle = WindowStyle.ToolWindow;
|
||||||
|
|
||||||
|
// ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口
|
||||||
|
navWin.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 按钮点击触发标准基准页面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void OnStandardPageButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
StandardPage standardPage = new StandardPage();
|
||||||
|
NavigationWindow navWin = new NavigationWindow();
|
||||||
|
navWin.Width = 972;
|
||||||
|
navWin.Height = 648;
|
||||||
|
//navWin.ResizeMode = ResizeMode.NoResize;
|
||||||
|
navWin.Content = standardPage;
|
||||||
|
navWin.ShowsNavigationUI = false;
|
||||||
|
navWin.Title = "主标定";
|
||||||
|
|
||||||
|
|
||||||
|
// ✅ 新增:设定父窗口、样式与居中弹出
|
||||||
|
navWin.Owner = Application.Current.MainWindow; // 绑定主窗口
|
||||||
|
navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出
|
||||||
|
navWin.WindowStyle = WindowStyle.ToolWindow;
|
||||||
|
|
||||||
|
// ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口
|
||||||
|
navWin.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 按钮点击触发Gauge页面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void OnGaugePageButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
GaugePage gaugePage = new GaugePage();
|
||||||
|
NavigationWindow navWin = new NavigationWindow();
|
||||||
|
navWin.Content = gaugePage;
|
||||||
|
navWin.ShowsNavigationUI = false;
|
||||||
|
navWin.Width = 1080;
|
||||||
|
navWin.Height = 720;
|
||||||
|
navWin.Title = "Gauge R&&R";
|
||||||
|
|
||||||
|
// ✅ 新增:设定父窗口、样式与居中弹出
|
||||||
|
navWin.Owner = Application.Current.MainWindow; // 绑定主窗口
|
||||||
|
navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出
|
||||||
|
navWin.WindowStyle = WindowStyle.ToolWindow;
|
||||||
|
|
||||||
|
// ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口
|
||||||
|
navWin.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 按钮点击触发CgCgk页面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void OnCgCgkPageButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
CgCgkPage cgCgkPage = new CgCgkPage();
|
||||||
|
NavigationWindow navWin = new NavigationWindow();
|
||||||
|
navWin.Content = cgCgkPage;
|
||||||
|
navWin.ShowsNavigationUI = false;
|
||||||
|
navWin.Title = "CgCgk";
|
||||||
|
|
||||||
|
|
||||||
|
// ✅ 新增:设定父窗口、样式与居中弹出
|
||||||
|
navWin.Owner = Application.Current.MainWindow; // 绑定主窗口
|
||||||
|
navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出
|
||||||
|
navWin.WindowStyle = WindowStyle.ToolWindow;
|
||||||
|
|
||||||
|
// ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口
|
||||||
|
navWin.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 按钮点击触发系统设置页面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void OnSysSetPageButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
SysSetPage sysSetPage = new SysSetPage();
|
||||||
|
NavigationWindow navWin = new NavigationWindow();
|
||||||
|
navWin.Width = 810;
|
||||||
|
navWin.Height = 600;
|
||||||
|
navWin.ResizeMode = ResizeMode.NoResize;
|
||||||
|
navWin.Content = sysSetPage;
|
||||||
|
navWin.ShowsNavigationUI = false;
|
||||||
|
navWin.Title = "系统设置";
|
||||||
|
|
||||||
|
|
||||||
|
// ✅ 新增:设定父窗口、样式与居中弹出
|
||||||
|
navWin.Owner = Application.Current.MainWindow; // 绑定主窗口
|
||||||
|
navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出
|
||||||
|
navWin.WindowStyle = WindowStyle.ToolWindow;
|
||||||
|
|
||||||
|
// ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口
|
||||||
|
navWin.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 关闭和测试按钮
|
||||||
|
/// <summary>
|
||||||
|
/// 按钮点击触发关闭页面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void OnCloseMainWindowButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
this.Close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 测试按钮
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void OnDemoButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
//LineBarChartDemo lineBarChartDemo = new LineBarChartDemo();
|
||||||
|
//lineBarChartDemo.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 等级选择下拉框变化事件处理
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void LevelComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is ComboBox comboBox && comboBox.SelectedItem is ComboBoxItem selectedItem)
|
||||||
|
{
|
||||||
|
// 根据选择的Tag确定等级
|
||||||
|
SensorLevel selectedLevel = SensorLevel.Medium; // 默认值
|
||||||
|
switch (selectedItem.Tag?.ToString())
|
||||||
|
{
|
||||||
|
case "Low":
|
||||||
|
selectedLevel = SensorLevel.Low;
|
||||||
|
break;
|
||||||
|
case "Medium":
|
||||||
|
selectedLevel = SensorLevel.Medium;
|
||||||
|
break;
|
||||||
|
case "High":
|
||||||
|
selectedLevel = SensorLevel.High;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新所有传感器图表的等级
|
||||||
|
Sensor1.Level = selectedLevel;
|
||||||
|
Sensor2.Level = selectedLevel;
|
||||||
|
Sensor3.Level = selectedLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
58
Utils/InitChart.cs
Normal file
58
Utils/InitChart.cs
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
using LiveCharts;
|
||||||
|
using LiveCharts.Wpf;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using WpfApp.src.config;
|
||||||
|
|
||||||
|
namespace WpfApp.Utils;
|
||||||
|
|
||||||
|
public static class InitChart
|
||||||
|
{
|
||||||
|
public static void InitCartesianChart(CartesianChart chart, ChartConfig config)
|
||||||
|
{
|
||||||
|
chart.Series = new SeriesCollection();
|
||||||
|
|
||||||
|
// 柱状图
|
||||||
|
if (config.ColumnData != null && config.ColumnData.Count > 0)
|
||||||
|
{
|
||||||
|
chart.Series.Add(new ColumnSeries
|
||||||
|
{
|
||||||
|
Title = "柱状数据",
|
||||||
|
Values = new ChartValues<double>(config.ColumnData)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标准线条
|
||||||
|
foreach (var line in config.LineConfigs)
|
||||||
|
{
|
||||||
|
var lineSeries = new LineSeries
|
||||||
|
{
|
||||||
|
Title = line.Title,
|
||||||
|
Values = new ChartValues<double>(line.Values),
|
||||||
|
Stroke = line.Stroke ?? Brushes.Black,
|
||||||
|
StrokeThickness = 2,
|
||||||
|
Fill = Brushes.Transparent,
|
||||||
|
DataLabels = line.ShowLabel,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (line.ShowLabel)
|
||||||
|
lineSeries.LabelPoint = value => $"{value.Y:0.##} {line.Unit}";
|
||||||
|
|
||||||
|
chart.Series.Add(lineSeries);
|
||||||
|
}
|
||||||
|
|
||||||
|
// X轴
|
||||||
|
chart.AxisX.Clear();
|
||||||
|
chart.AxisX.Add(new Axis
|
||||||
|
{
|
||||||
|
Title = config.XTitle ?? "",
|
||||||
|
Labels = config.Labels
|
||||||
|
});
|
||||||
|
|
||||||
|
// Y轴
|
||||||
|
chart.AxisY.Clear();
|
||||||
|
chart.AxisY.Add(new Axis
|
||||||
|
{
|
||||||
|
Title = config.YTitle ?? ""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,402 +1,409 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
|
||||||
namespace WpfApp.src.components
|
namespace WpfApp.src.components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 刻度线数据结构
|
||||||
|
/// </summary>
|
||||||
|
public class ScaleLine
|
||||||
{
|
{
|
||||||
/// <summary>
|
public double Y1 { get; set; }
|
||||||
/// 刻度线数据结构
|
public double Y2 { get; set; }
|
||||||
/// </summary>
|
public double X1 { get; set; }
|
||||||
public class ScaleLine
|
public double X2 { get; set; }
|
||||||
|
public double StrokeThickness { get; set; }
|
||||||
|
public string Label { get; set; }
|
||||||
|
public double LabelX { get; set; }
|
||||||
|
public double LabelY { get; set; }
|
||||||
|
public bool IsMainScale { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SensorChart.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class SensorChart : UserControl, INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
public SensorChart()
|
||||||
{
|
{
|
||||||
public double Y1 { get; set; }
|
InitializeComponent();
|
||||||
public double Y2 { get; set; }
|
DataContext = this;
|
||||||
public double X1 { get; set; }
|
|
||||||
public double X2 { get; set; }
|
// 设置默认值
|
||||||
public double StrokeThickness { get; set; }
|
SensorName = "传感器";
|
||||||
public string Label { get; set; }
|
HeaderBackground = new SolidColorBrush(Color.FromRgb(230, 243, 255)); // #E6F3FF
|
||||||
public double LabelX { get; set; }
|
Value = 0;
|
||||||
public double LabelY { get; set; }
|
RedLineValues = new List<double>();
|
||||||
public bool IsMainScale { get; set; }
|
Level = SensorLevel.Medium; // 默认中等
|
||||||
|
|
||||||
|
// 生成初始刻度
|
||||||
|
GenerateScaleLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 传感器等级
|
||||||
|
public static readonly DependencyProperty LevelProperty =
|
||||||
|
DependencyProperty.Register("Level", typeof(SensorLevel), typeof(SensorChart),
|
||||||
|
new PropertyMetadata(SensorLevel.Medium, OnLevelChanged));
|
||||||
|
|
||||||
|
public SensorLevel Level
|
||||||
|
{
|
||||||
|
get { return (SensorLevel)GetValue(LevelProperty); }
|
||||||
|
set { SetValue(LevelProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnLevelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var control = d as SensorChart;
|
||||||
|
control?.OnLevelChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
#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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ScaleLine> _scaleLines = new List<ScaleLine>();
|
||||||
|
public List<ScaleLine> ScaleLines
|
||||||
|
{
|
||||||
|
get { return _scaleLines; }
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
_scaleLines = value;
|
||||||
|
OnPropertyChanged(nameof(ScaleLines));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当前等级的最小值
|
||||||
|
public double MinValue
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
switch (Level)
|
||||||
|
{
|
||||||
|
case SensorLevel.Low: return -20;
|
||||||
|
case SensorLevel.Medium: return -40;
|
||||||
|
case SensorLevel.High: return -60;
|
||||||
|
default: return -40;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当前等级的最大值
|
||||||
|
public double MaxValue
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
switch (Level)
|
||||||
|
{
|
||||||
|
case SensorLevel.Low: return 20;
|
||||||
|
case SensorLevel.Medium: return 40;
|
||||||
|
case SensorLevel.High: return 60;
|
||||||
|
default: return 40;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 私有方法
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 等级改变时的处理
|
||||||
|
/// </summary>
|
||||||
|
private void OnLevelChanged()
|
||||||
|
{
|
||||||
|
OnPropertyChanged(nameof(Level));
|
||||||
|
OnPropertyChanged(nameof(MinValue));
|
||||||
|
OnPropertyChanged(nameof(MaxValue));
|
||||||
|
GenerateScaleLines();
|
||||||
|
UpdateBarPosition();
|
||||||
|
UpdateRedLinePositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SensorChart.xaml 的交互逻辑
|
/// 生成刻度线
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class SensorChart : UserControl, INotifyPropertyChanged
|
private void GenerateScaleLines()
|
||||||
{
|
{
|
||||||
public SensorChart()
|
var lines = new List<ScaleLine>();
|
||||||
|
double minVal = MinValue;
|
||||||
|
double maxVal = MaxValue;
|
||||||
|
|
||||||
|
// 根据等级确定刻度间隔
|
||||||
|
double mainInterval = (maxVal - minVal) / 8; // 8个主刻度间隔
|
||||||
|
double subInterval = mainInterval / 4; // 每个主刻度间隔4个小刻度
|
||||||
|
|
||||||
|
// 生成主刻度线
|
||||||
|
for (int i = 0; i <= 8; i++)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
double value = maxVal - i * mainInterval;
|
||||||
DataContext = this;
|
double y = ValueToY(value);
|
||||||
|
|
||||||
// 设置默认值
|
lines.Add(new ScaleLine
|
||||||
SensorName = "传感器";
|
{
|
||||||
HeaderBackground = new SolidColorBrush(Color.FromRgb(230, 243, 255)); // #E6F3FF
|
X1 = 40,
|
||||||
Value = 0;
|
Y1 = y,
|
||||||
RedLineValues = new List<double>();
|
X2 = 130,
|
||||||
Level = SensorLevel.Medium; // 默认中等
|
Y2 = y,
|
||||||
|
StrokeThickness = 1,
|
||||||
|
Label = value.ToString("0"),
|
||||||
|
LabelX = 135,
|
||||||
|
LabelY = y - 5,
|
||||||
|
IsMainScale = true
|
||||||
|
});
|
||||||
|
|
||||||
// 生成初始刻度
|
// 生成小刻度线(除了最后一个主刻度)
|
||||||
GenerateScaleLines();
|
if (i < 8)
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 传感器等级
|
|
||||||
public static readonly DependencyProperty LevelProperty =
|
|
||||||
DependencyProperty.Register("Level", typeof(SensorLevel), typeof(SensorChart),
|
|
||||||
new PropertyMetadata(SensorLevel.Medium, OnLevelChanged));
|
|
||||||
|
|
||||||
public SensorLevel Level
|
|
||||||
{
|
|
||||||
get { return (SensorLevel)GetValue(LevelProperty); }
|
|
||||||
set { SetValue(LevelProperty, value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void OnLevelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
||||||
{
|
|
||||||
var control = d as SensorChart;
|
|
||||||
control?.OnLevelChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 计算属性
|
|
||||||
|
|
||||||
private double _barTop;
|
|
||||||
public double BarTop
|
|
||||||
{
|
|
||||||
get { return _barTop; }
|
|
||||||
private set
|
|
||||||
{
|
{
|
||||||
_barTop = value;
|
for (int j = 1; j < 4; j++)
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<ScaleLine> _scaleLines = new List<ScaleLine>();
|
|
||||||
public List<ScaleLine> ScaleLines
|
|
||||||
{
|
|
||||||
get { return _scaleLines; }
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
_scaleLines = value;
|
|
||||||
OnPropertyChanged(nameof(ScaleLines));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 当前等级的最小值
|
|
||||||
public double MinValue
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
switch (Level)
|
|
||||||
{
|
{
|
||||||
case SensorLevel.Low: return -20;
|
double subValue = value - j * subInterval;
|
||||||
case SensorLevel.Medium: return -40;
|
double subY = ValueToY(subValue);
|
||||||
case SensorLevel.High: return -60;
|
|
||||||
default: return -40;
|
lines.Add(new ScaleLine
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 当前等级的最大值
|
|
||||||
public double MaxValue
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
switch (Level)
|
|
||||||
{
|
|
||||||
case SensorLevel.Low: return 20;
|
|
||||||
case SensorLevel.Medium: return 40;
|
|
||||||
case SensorLevel.High: return 60;
|
|
||||||
default: return 40;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 私有方法
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 等级改变时的处理
|
|
||||||
/// </summary>
|
|
||||||
private void OnLevelChanged()
|
|
||||||
{
|
|
||||||
OnPropertyChanged(nameof(Level));
|
|
||||||
OnPropertyChanged(nameof(MinValue));
|
|
||||||
OnPropertyChanged(nameof(MaxValue));
|
|
||||||
GenerateScaleLines();
|
|
||||||
UpdateBarPosition();
|
|
||||||
UpdateRedLinePositions();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 生成刻度线
|
|
||||||
/// </summary>
|
|
||||||
private void GenerateScaleLines()
|
|
||||||
{
|
|
||||||
var lines = new List<ScaleLine>();
|
|
||||||
double minVal = MinValue;
|
|
||||||
double maxVal = MaxValue;
|
|
||||||
|
|
||||||
// 根据等级确定刻度间隔
|
|
||||||
double mainInterval = (maxVal - minVal) / 8; // 8个主刻度间隔
|
|
||||||
double subInterval = mainInterval / 4; // 每个主刻度间隔4个小刻度
|
|
||||||
|
|
||||||
// 生成主刻度线
|
|
||||||
for (int i = 0; i <= 8; i++)
|
|
||||||
{
|
|
||||||
double value = maxVal - i * mainInterval;
|
|
||||||
double y = ValueToY(value);
|
|
||||||
|
|
||||||
lines.Add(new ScaleLine
|
|
||||||
{
|
|
||||||
X1 = 40,
|
|
||||||
Y1 = y,
|
|
||||||
X2 = 130,
|
|
||||||
Y2 = y,
|
|
||||||
StrokeThickness = 1,
|
|
||||||
Label = value.ToString("0"),
|
|
||||||
LabelX = 135,
|
|
||||||
LabelY = y - 5,
|
|
||||||
IsMainScale = true
|
|
||||||
});
|
|
||||||
|
|
||||||
// 生成小刻度线(除了最后一个主刻度)
|
|
||||||
if (i < 8)
|
|
||||||
{
|
|
||||||
for (int j = 1; j < 4; j++)
|
|
||||||
{
|
{
|
||||||
double subValue = value - j * subInterval;
|
X1 = 40,
|
||||||
double subY = ValueToY(subValue);
|
Y1 = subY,
|
||||||
|
X2 = 125,
|
||||||
lines.Add(new ScaleLine
|
Y2 = subY,
|
||||||
{
|
StrokeThickness = 0.5,
|
||||||
X1 = 40,
|
Label = "",
|
||||||
Y1 = subY,
|
LabelX = 0,
|
||||||
X2 = 125,
|
LabelY = 0,
|
||||||
Y2 = subY,
|
IsMainScale = false
|
||||||
StrokeThickness = 0.5,
|
});
|
||||||
Label = "",
|
|
||||||
LabelX = 0,
|
|
||||||
LabelY = 0,
|
|
||||||
IsMainScale = false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScaleLines = lines;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
ScaleLines = lines;
|
||||||
/// 将数值转换为Y坐标位置
|
|
||||||
/// 根据当前等级动态计算刻度范围
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">数值</param>
|
|
||||||
/// <returns>Y坐标</returns>
|
|
||||||
private double ValueToY(double value)
|
|
||||||
{
|
|
||||||
double minVal = MinValue;
|
|
||||||
double maxVal = MaxValue;
|
|
||||||
|
|
||||||
// 限制数值范围
|
|
||||||
value = Math.Max(minVal, Math.Min(maxVal, value));
|
|
||||||
|
|
||||||
// 线性映射:maxVal对应Y=20,minVal对应Y=420
|
|
||||||
double range = maxVal - minVal;
|
|
||||||
return 220 - ((value - minVal) / range - 0.5) * 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <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>
|
|
||||||
/// <param name="level">传感器等级</param>
|
|
||||||
public void SetSensorData(string name, double value, List<double> redLines = null, Color? headerColor = null, SensorLevel? level = null)
|
|
||||||
{
|
|
||||||
SensorName = name;
|
|
||||||
Value = value;
|
|
||||||
|
|
||||||
if (redLines != null)
|
|
||||||
{
|
|
||||||
RedLineValues = new List<double>(redLines);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (headerColor.HasValue)
|
|
||||||
{
|
|
||||||
HeaderBackground = new SolidColorBrush(headerColor.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (level.HasValue)
|
|
||||||
{
|
|
||||||
Level = level.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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将数值转换为Y坐标位置
|
||||||
|
/// 根据当前等级动态计算刻度范围
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">数值</param>
|
||||||
|
/// <returns>Y坐标</returns>
|
||||||
|
private double ValueToY(double value)
|
||||||
|
{
|
||||||
|
double minVal = MinValue;
|
||||||
|
double maxVal = MaxValue;
|
||||||
|
|
||||||
|
// 限制数值范围
|
||||||
|
value = Math.Max(minVal, Math.Min(maxVal, value));
|
||||||
|
|
||||||
|
// 线性映射:maxVal对应Y=20,minVal对应Y=420
|
||||||
|
double range = maxVal - minVal;
|
||||||
|
return 220 - ((value - minVal) / range - 0.5) * 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
/// <param name="level">传感器等级</param>
|
||||||
|
public void SetSensorData(string name, double value, List<double> redLines = null, Color? headerColor = null, SensorLevel? level = null)
|
||||||
|
{
|
||||||
|
SensorName = name;
|
||||||
|
Value = value;
|
||||||
|
|
||||||
|
if (redLines != null)
|
||||||
|
{
|
||||||
|
RedLineValues = new List<double>(redLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headerColor.HasValue)
|
||||||
|
{
|
||||||
|
HeaderBackground = new SolidColorBrush(headerColor.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level.HasValue)
|
||||||
|
{
|
||||||
|
Level = level.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
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 传感器等级枚举
|
||||||
|
/// </summary>
|
||||||
|
public enum SensorLevel
|
||||||
|
{
|
||||||
|
Low, // 低等:-20到20
|
||||||
|
Medium, // 中等:-40到40
|
||||||
|
High // 高等:-60到60
|
||||||
}
|
}
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
namespace WpfApp.src.components
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 传感器等级枚举
|
|
||||||
/// </summary>
|
|
||||||
public enum SensorLevel
|
|
||||||
{
|
|
||||||
Low, // 低等:-20到20
|
|
||||||
Medium, // 中等:-40到40
|
|
||||||
High // 高等:-60到60
|
|
||||||
}
|
|
||||||
}
|
|
||||||
36
src/config/ChartConfig.cs
Normal file
36
src/config/ChartConfig.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace WpfApp.src.config;
|
||||||
|
|
||||||
|
public class ChartConfig
|
||||||
|
{
|
||||||
|
public List<double> ColumnData { get; set; } = new();
|
||||||
|
public List<LineConfig> LineConfigs { get; set; } = new();
|
||||||
|
public List<string> Labels { get; set; } = new();
|
||||||
|
public string XTitle { get; set; }
|
||||||
|
public string YTitle { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LineConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 曲线标题
|
||||||
|
/// </summary>
|
||||||
|
public string Title { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 曲线的值
|
||||||
|
/// </summary>
|
||||||
|
public List<double> Values { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 曲线颜色
|
||||||
|
/// </summary>
|
||||||
|
public Brush Stroke { get; set; } = Brushes.Black;
|
||||||
|
/// <summary>
|
||||||
|
/// 是否显示数据点上的标签
|
||||||
|
/// </summary>
|
||||||
|
public bool ShowLabel { get; set; } = true;
|
||||||
|
/// <summary>
|
||||||
|
/// 单位
|
||||||
|
/// </summary>
|
||||||
|
public string Unit { get; set; } = "Hz";
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user