diff --git a/CurveModule/ViewModels/CurveRecallViewModel.cs b/CurveModule/ViewModels/CurveRecallViewModel.cs
index a2fe064..888f4d6 100644
--- a/CurveModule/ViewModels/CurveRecallViewModel.cs
+++ b/CurveModule/ViewModels/CurveRecallViewModel.cs
@@ -1,71 +1,381 @@
using Logger;
-using MahApps.Metro.Controls;
-using Model.Entity;
-using Model.Models;
-using NLog.Targets;
using OxyPlot;
-using Service.Interface;
+using OxyPlot.Axes;
+using OxyPlot.Legends;
+using OxyPlot.Series;
+using Prism.Commands;
using System;
-using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
-using System.Data;
-using System.Diagnostics;
+using System.IO;
using System.Linq;
using System.Text;
-using System.Threading.Tasks;
using System.Windows.Input;
-using System.Windows.Threading;
-
-using UIShare.GlobalVariable;
-using UIShare.UIViewModel;
using UIShare.ViewModelBase;
namespace CurveModule.ViewModels
-
-
{
+ ///
+ /// 曲线回读:加载 RecordView 导出的 CSV 文件,按 (MonitorName, Scope) 分组绘制曲线。
+ ///
public class CurveRecallViewModel : NavigateViewModelBase, IRegionMemberLifetime, IDisposable
{
#region 属性
public bool KeepAlive => true;
+
+ public PlotModel Plot { get; }
+
+ /// 已加载的曲线通道列表
+ public ObservableCollection Channels { get; } = new();
+
+ private CurveRecallChannelVM? _selectedChannel;
+ public CurveRecallChannelVM? SelectedChannel
+ {
+ get => _selectedChannel;
+ set => SetProperty(ref _selectedChannel, value);
+ }
+
+ private string _statusMessage = "请加载 CSV 文件以回读曲线";
+ public string StatusMessage
+ {
+ get => _statusMessage;
+ set => SetProperty(ref _statusMessage, value);
+ }
#endregion
#region 命令
-
+ public ICommand LoadCsvCommand { get; }
+ public ICommand ResetViewCommand { get; }
+ public ICommand ClearCommand { get; }
#endregion
#region 私有字段
-
+ // 颜色调色盘(与 MonitorView 一致)
+ private static readonly OxyColor[] _palette =
+ {
+ OxyColors.SteelBlue, OxyColors.IndianRed, OxyColors.SeaGreen,
+ OxyColors.DarkOrange, OxyColors.MediumPurple, OxyColors.Goldenrod,
+ OxyColors.Teal, OxyColors.Crimson, OxyColors.OliveDrab
+ };
+ private int _colorIndex;
#endregion
+
public CurveRecallViewModel(IContainerProvider containerProvider) : base(containerProvider)
{
-
+ Plot = BuildEmptyPlot();
+ LoadCsvCommand = new DelegateCommand(OnLoadCsv);
+ ResetViewCommand = new DelegateCommand(OnResetView);
+ ClearCommand = new DelegateCommand(OnClear);
}
#region 命令处理
+ ///
+ /// 打开 CSV 文件对话框,解析数据并按 (MonitorName, Scope) 分组绘制曲线。
+ ///
+ private void OnLoadCsv()
+ {
+ try
+ {
+ var dlg = new Microsoft.Win32.OpenFileDialog
+ {
+ Filter = "CSV 文件 (*.csv)|*.csv|所有文件|*.*",
+ Title = "选择要加载的监测数据 CSV 文件"
+ };
+ if (dlg.ShowDialog() != true) return;
-
+ var records = ParseCsv(dlg.FileName);
+ if (records.Count == 0)
+ {
+ StatusMessage = "CSV 文件为空或格式不正确";
+ return;
+ }
+ // 按 (MonitorName, Scope) 分组
+ var groups = records.GroupBy(r => (r.MonitorName, r.Scope))
+ .OrderBy(g => g.Key.MonitorName)
+ .ThenBy(g => g.Key.Scope);
+
+ // 清空旧数据
+ ClearPlotAndChannels();
+
+ foreach (var group in groups)
+ {
+ var color = _palette[_colorIndex % _palette.Length];
+ _colorIndex++;
+
+ string displayName = string.IsNullOrEmpty(group.Key.Scope)
+ ? group.Key.MonitorName
+ : $"{group.Key.MonitorName} [{group.Key.Scope}]";
+
+ var channel = new CurveRecallChannelVM
+ {
+ MonitorName = group.Key.MonitorName,
+ Scope = group.Key.Scope,
+ DisplayName = displayName,
+ Color = color,
+ IsDisplayed = true
+ };
+
+ // 创建 LineSeries 并填充数据点
+ channel.Series = new LineSeries
+ {
+ Title = displayName,
+ Color = color,
+ StrokeThickness = 1.5
+ };
+
+ // 按时间排序
+ var sortedPoints = group.OrderBy(r => r.CreateTime);
+ foreach (var point in sortedPoints)
+ {
+ channel.Series.Points.Add(new DataPoint(point.CreateTime.ToOADate(), point.MonitorValue));
+ }
+
+ channel.PropertyChanged += OnChannelPropertyChanged;
+
+ Plot.Series.Add(channel.Series);
+ Channels.Add(channel);
+ }
+
+ Plot.InvalidatePlot(true);
+ StatusMessage = $"已加载 {Path.GetFileName(dlg.FileName)},共 {Channels.Count} 条曲线,{records.Count} 个数据点";
+ LoggerHelper.Info($"曲线回读:加载 {dlg.FileName},{Channels.Count} 条曲线,{records.Count} 个数据点");
+ }
+ catch (Exception ex)
+ {
+ LoggerHelper.Error($"加载 CSV 失败:{ex.Message}");
+ StatusMessage = $"加载失败:{ex.Message}";
+ }
+ }
+
+ private void OnResetView()
+ {
+ Plot.ResetAllAxes();
+ Plot.InvalidatePlot(false);
+ StatusMessage = "视图已复原";
+ }
+
+ private void OnClear()
+ {
+ ClearPlotAndChannels();
+ Plot.InvalidatePlot(true);
+ StatusMessage = "已清空,请重新加载 CSV 文件";
+ }
+ #endregion
+
+ #region CSV 解析
+ ///
+ /// 解析 RecordView 导出的 CSV 文件,返回监测记录列表。
+ ///
+ private static List ParseCsv(string path)
+ {
+ var results = new List();
+
+ using var sr = new StreamReader(path, Encoding.UTF8);
+
+ // 读取表头
+ string? headerLine = sr.ReadLine();
+ if (headerLine == null) return results;
+
+ var headers = ParseCsvLine(headerLine);
+ int monitorNameIdx = headers.FindIndex(h => h.Trim() == "MonitorName");
+ int monitorValueIdx = headers.FindIndex(h => h.Trim() == "MonitorValue");
+ int scopeIdx = headers.FindIndex(h => h.Trim() == "Scope");
+ int createTimeIdx = headers.FindIndex(h => h.Trim() == "CreateTime");
+
+ if (monitorNameIdx < 0 || monitorValueIdx < 0 || scopeIdx < 0 || createTimeIdx < 0)
+ return results;
+
+ int maxIdx = Math.Max(monitorNameIdx, Math.Max(monitorValueIdx, Math.Max(scopeIdx, createTimeIdx)));
+
+ string? line;
+ while ((line = sr.ReadLine()) != null)
+ {
+ if (string.IsNullOrWhiteSpace(line)) continue;
+ var fields = ParseCsvLine(line);
+ if (fields.Count <= maxIdx) continue;
+
+ if (!double.TryParse(fields[monitorValueIdx].Trim(), out double value)) continue;
+ if (!DateTime.TryParse(fields[createTimeIdx].Trim(), out DateTime createTime)) continue;
+
+ results.Add(new MonitorRecord
+ {
+ MonitorName = fields[monitorNameIdx].Trim(),
+ MonitorValue = value,
+ Scope = fields[scopeIdx].Trim(),
+ CreateTime = createTime
+ });
+ }
+
+ return results;
+ }
+
+ ///
+ /// 解析单行 CSV,正确处理引号转义。
+ ///
+ private static List ParseCsvLine(string line)
+ {
+ var fields = new List();
+ bool inQuotes = false;
+ var sb = new StringBuilder();
+
+ for (int i = 0; i < line.Length; i++)
+ {
+ char c = line[i];
+ if (inQuotes)
+ {
+ if (c == '"')
+ {
+ if (i + 1 < line.Length && line[i + 1] == '"')
+ {
+ sb.Append('"');
+ i++;
+ }
+ else
+ {
+ inQuotes = false;
+ }
+ }
+ else
+ {
+ sb.Append(c);
+ }
+ }
+ else
+ {
+ if (c == '"')
+ {
+ inQuotes = true;
+ }
+ else if (c == ',')
+ {
+ fields.Add(sb.ToString());
+ sb.Clear();
+ }
+ else
+ {
+ sb.Append(c);
+ }
+ }
+ }
+
+ fields.Add(sb.ToString());
+ return fields;
+ }
+ #endregion
+
+ #region OxyPlot 构建
+ ///
+ /// 构建空的 OxyPlot 模型(与 MonitorView 完全一致的配置)。
+ ///
+ private static PlotModel BuildEmptyPlot()
+ {
+ var pm = new PlotModel
+ {
+ Title = "曲线回读",
+ PlotAreaBorderColor = OxyColors.LightGray,
+ Background = OxyColors.White
+ };
+ pm.Axes.Add(new DateTimeAxis
+ {
+ Position = AxisPosition.Bottom,
+ Title = "时间",
+ StringFormat = "HH:mm:ss",
+ MajorGridlineStyle = LineStyle.Dot,
+ MinorGridlineStyle = LineStyle.None
+ });
+ pm.Axes.Add(new LinearAxis
+ {
+ Position = AxisPosition.Left,
+ Title = "值",
+ MajorGridlineStyle = LineStyle.Dot,
+ MinorGridlineStyle = LineStyle.None
+ });
+ pm.Legends.Add(new Legend
+ {
+ LegendPosition = LegendPosition.RightTop,
+ LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
+ LegendBorder = OxyColors.LightGray
+ });
+ return pm;
+ }
#endregion
#region 辅助方法
+ private void OnChannelPropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName != nameof(CurveRecallChannelVM.IsDisplayed)) return;
+ if (sender is not CurveRecallChannelVM channel) return;
+ if (channel.IsDisplayed)
+ {
+ if (channel.Series != null && !Plot.Series.Contains(channel.Series))
+ {
+ Plot.Series.Add(channel.Series);
+ }
+ }
+ else
+ {
+ if (channel.Series != null)
+ {
+ Plot.Series.Remove(channel.Series);
+ }
+ }
+ Plot.InvalidatePlot(true);
+ }
+ private void ClearPlotAndChannels()
+ {
+ foreach (var ch in Channels)
+ {
+ ch.PropertyChanged -= OnChannelPropertyChanged;
+ }
+ Plot.Series.Clear();
+ Channels.Clear();
+ _colorIndex = 0;
+ }
#endregion
- #region 生命周期
+ #region 生命周期
public override void OnNavigatedTo(NavigationContext navigationContext)
{
-
}
public void Dispose()
{
-
+ ClearPlotAndChannels();
+ }
+ #endregion
+ }
+
+ ///
+ /// CSV 监测记录(单行数据)。
+ ///
+ internal class MonitorRecord
+ {
+ public string MonitorName { get; set; } = string.Empty;
+ public double MonitorValue { get; set; }
+ public string Scope { get; set; } = string.Empty;
+ public DateTime CreateTime { get; set; }
+ }
+
+ ///
+ /// 曲线回读通道:MonitorName + Scope 唯一标识一条曲线。
+ ///
+ public class CurveRecallChannelVM : Prism.Mvvm.BindableBase
+ {
+ public string MonitorName { get; set; } = string.Empty;
+ public string Scope { get; set; } = string.Empty;
+ public string DisplayName { get; set; } = string.Empty;
+ public OxyColor Color { get; set; } = OxyColors.SteelBlue;
+
+ private bool _isDisplayed = true;
+ public bool IsDisplayed
+ {
+ get => _isDisplayed;
+ set => SetProperty(ref _isDisplayed, value);
}
- #endregion
-
+ public LineSeries? Series { get; set; }
}
}
diff --git a/CurveModule/Views/CurveRecallView.xaml b/CurveModule/Views/CurveRecallView.xaml
index 8de793a..18ecbb9 100644
--- a/CurveModule/Views/CurveRecallView.xaml
+++ b/CurveModule/Views/CurveRecallView.xaml
@@ -1,14 +1,158 @@
-
-
-
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:prism="http://prismlibrary.com/"
+ xmlns:oxy="http://oxyplot.org/wpf"
+ xmlns:converters="clr-namespace:UIShare.Converters;assembly=UIShare"
+ prism:ViewModelLocator.AutoWireViewModel="True"
+ mc:Ignorable="d"
+ d:DesignHeight="700"
+ d:DesignWidth="1200">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MonitorModule/MonitorModule.cs b/MonitorModule/MonitorModule.cs
index a931337..fb6d2f5 100644
--- a/MonitorModule/MonitorModule.cs
+++ b/MonitorModule/MonitorModule.cs
@@ -17,7 +17,6 @@ namespace MonitorModule
{
containerRegistry.RegisterForNavigation("MonitorView");
containerRegistry.RegisterForNavigation("RecordView");
- containerRegistry.RegisterForNavigation("CurveRecallView");
containerRegistry.RegisterDialog("ValueLimitView");
}
}
diff --git a/MonitorModule/ViewModels/CurveRecallViewModel.cs b/MonitorModule/ViewModels/CurveRecallViewModel.cs
deleted file mode 100644
index 5f22749..0000000
--- a/MonitorModule/ViewModels/CurveRecallViewModel.cs
+++ /dev/null
@@ -1,381 +0,0 @@
-using Logger;
-using OxyPlot;
-using OxyPlot.Axes;
-using OxyPlot.Legends;
-using OxyPlot.Series;
-using Prism.Commands;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Windows.Input;
-using UIShare.ViewModelBase;
-
-namespace MonitorModule.ViewModels
-{
- ///
- /// 曲线回读:加载 RecordView 导出的 CSV 文件,按 (MonitorName, Scope) 分组绘制曲线。
- ///
- public class CurveRecallViewModel : NavigateViewModelBase, IRegionMemberLifetime, IDisposable
- {
- #region 属性
- public bool KeepAlive => true;
-
- public PlotModel Plot { get; }
-
- /// 已加载的曲线通道列表
- public ObservableCollection Channels { get; } = new();
-
- private CurveRecallChannelVM? _selectedChannel;
- public CurveRecallChannelVM? SelectedChannel
- {
- get => _selectedChannel;
- set => SetProperty(ref _selectedChannel, value);
- }
-
- private string _statusMessage = "请加载 CSV 文件以回读曲线";
- public string StatusMessage
- {
- get => _statusMessage;
- set => SetProperty(ref _statusMessage, value);
- }
- #endregion
-
- #region 命令
- public ICommand LoadCsvCommand { get; }
- public ICommand ResetViewCommand { get; }
- public ICommand ClearCommand { get; }
- #endregion
-
- #region 私有字段
- // 颜色调色盘(与 MonitorView 一致)
- private static readonly OxyColor[] _palette =
- {
- OxyColors.SteelBlue, OxyColors.IndianRed, OxyColors.SeaGreen,
- OxyColors.DarkOrange, OxyColors.MediumPurple, OxyColors.Goldenrod,
- OxyColors.Teal, OxyColors.Crimson, OxyColors.OliveDrab
- };
- private int _colorIndex;
- #endregion
-
- public CurveRecallViewModel(IContainerProvider containerProvider) : base(containerProvider)
- {
- Plot = BuildEmptyPlot();
- LoadCsvCommand = new DelegateCommand(OnLoadCsv);
- ResetViewCommand = new DelegateCommand(OnResetView);
- ClearCommand = new DelegateCommand(OnClear);
- }
-
- #region 命令处理
- ///
- /// 打开 CSV 文件对话框,解析数据并按 (MonitorName, Scope) 分组绘制曲线。
- ///
- private void OnLoadCsv()
- {
- try
- {
- var dlg = new Microsoft.Win32.OpenFileDialog
- {
- Filter = "CSV 文件 (*.csv)|*.csv|所有文件|*.*",
- Title = "选择要加载的监测数据 CSV 文件"
- };
- if (dlg.ShowDialog() != true) return;
-
- var records = ParseCsv(dlg.FileName);
- if (records.Count == 0)
- {
- StatusMessage = "CSV 文件为空或格式不正确";
- return;
- }
-
- // 按 (MonitorName, Scope) 分组
- var groups = records.GroupBy(r => (r.MonitorName, r.Scope))
- .OrderBy(g => g.Key.MonitorName)
- .ThenBy(g => g.Key.Scope);
-
- // 清空旧数据
- ClearPlotAndChannels();
-
- foreach (var group in groups)
- {
- var color = _palette[_colorIndex % _palette.Length];
- _colorIndex++;
-
- string displayName = string.IsNullOrEmpty(group.Key.Scope)
- ? group.Key.MonitorName
- : $"{group.Key.MonitorName} [{group.Key.Scope}]";
-
- var channel = new CurveRecallChannelVM
- {
- MonitorName = group.Key.MonitorName,
- Scope = group.Key.Scope,
- DisplayName = displayName,
- Color = color,
- IsDisplayed = true
- };
-
- // 创建 LineSeries 并填充数据点
- channel.Series = new LineSeries
- {
- Title = displayName,
- Color = color,
- StrokeThickness = 1.5
- };
-
- // 按时间排序
- var sortedPoints = group.OrderBy(r => r.CreateTime);
- foreach (var point in sortedPoints)
- {
- channel.Series.Points.Add(new DataPoint(point.CreateTime.ToOADate(), point.MonitorValue));
- }
-
- channel.PropertyChanged += OnChannelPropertyChanged;
-
- Plot.Series.Add(channel.Series);
- Channels.Add(channel);
- }
-
- Plot.InvalidatePlot(true);
- StatusMessage = $"已加载 {Path.GetFileName(dlg.FileName)},共 {Channels.Count} 条曲线,{records.Count} 个数据点";
- LoggerHelper.Info($"曲线回读:加载 {dlg.FileName},{Channels.Count} 条曲线,{records.Count} 个数据点");
- }
- catch (Exception ex)
- {
- LoggerHelper.Error($"加载 CSV 失败:{ex.Message}");
- StatusMessage = $"加载失败:{ex.Message}";
- }
- }
-
- private void OnResetView()
- {
- Plot.ResetAllAxes();
- Plot.InvalidatePlot(false);
- StatusMessage = "视图已复原";
- }
-
- private void OnClear()
- {
- ClearPlotAndChannels();
- Plot.InvalidatePlot(true);
- StatusMessage = "已清空,请重新加载 CSV 文件";
- }
- #endregion
-
- #region CSV 解析
- ///
- /// 解析 RecordView 导出的 CSV 文件,返回监测记录列表。
- ///
- private static List ParseCsv(string path)
- {
- var results = new List();
-
- using var sr = new StreamReader(path, Encoding.UTF8);
-
- // 读取表头
- string? headerLine = sr.ReadLine();
- if (headerLine == null) return results;
-
- var headers = ParseCsvLine(headerLine);
- int monitorNameIdx = headers.FindIndex(h => h.Trim() == "MonitorName");
- int monitorValueIdx = headers.FindIndex(h => h.Trim() == "MonitorValue");
- int scopeIdx = headers.FindIndex(h => h.Trim() == "Scope");
- int createTimeIdx = headers.FindIndex(h => h.Trim() == "CreateTime");
-
- if (monitorNameIdx < 0 || monitorValueIdx < 0 || scopeIdx < 0 || createTimeIdx < 0)
- return results;
-
- int maxIdx = Math.Max(monitorNameIdx, Math.Max(monitorValueIdx, Math.Max(scopeIdx, createTimeIdx)));
-
- string? line;
- while ((line = sr.ReadLine()) != null)
- {
- if (string.IsNullOrWhiteSpace(line)) continue;
- var fields = ParseCsvLine(line);
- if (fields.Count <= maxIdx) continue;
-
- if (!double.TryParse(fields[monitorValueIdx].Trim(), out double value)) continue;
- if (!DateTime.TryParse(fields[createTimeIdx].Trim(), out DateTime createTime)) continue;
-
- results.Add(new MonitorRecord
- {
- MonitorName = fields[monitorNameIdx].Trim(),
- MonitorValue = value,
- Scope = fields[scopeIdx].Trim(),
- CreateTime = createTime
- });
- }
-
- return results;
- }
-
- ///
- /// 解析单行 CSV,正确处理引号转义。
- ///
- private static List ParseCsvLine(string line)
- {
- var fields = new List();
- bool inQuotes = false;
- var sb = new StringBuilder();
-
- for (int i = 0; i < line.Length; i++)
- {
- char c = line[i];
- if (inQuotes)
- {
- if (c == '"')
- {
- if (i + 1 < line.Length && line[i + 1] == '"')
- {
- sb.Append('"');
- i++;
- }
- else
- {
- inQuotes = false;
- }
- }
- else
- {
- sb.Append(c);
- }
- }
- else
- {
- if (c == '"')
- {
- inQuotes = true;
- }
- else if (c == ',')
- {
- fields.Add(sb.ToString());
- sb.Clear();
- }
- else
- {
- sb.Append(c);
- }
- }
- }
-
- fields.Add(sb.ToString());
- return fields;
- }
- #endregion
-
- #region OxyPlot 构建
- ///
- /// 构建空的 OxyPlot 模型(与 MonitorView 完全一致的配置)。
- ///
- private static PlotModel BuildEmptyPlot()
- {
- var pm = new PlotModel
- {
- Title = "曲线回读",
- PlotAreaBorderColor = OxyColors.LightGray,
- Background = OxyColors.White
- };
- pm.Axes.Add(new DateTimeAxis
- {
- Position = AxisPosition.Bottom,
- Title = "时间",
- StringFormat = "HH:mm:ss",
- MajorGridlineStyle = LineStyle.Dot,
- MinorGridlineStyle = LineStyle.None
- });
- pm.Axes.Add(new LinearAxis
- {
- Position = AxisPosition.Left,
- Title = "值",
- MajorGridlineStyle = LineStyle.Dot,
- MinorGridlineStyle = LineStyle.None
- });
- pm.Legends.Add(new Legend
- {
- LegendPosition = LegendPosition.RightTop,
- LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
- LegendBorder = OxyColors.LightGray
- });
- return pm;
- }
- #endregion
-
- #region 辅助方法
- private void OnChannelPropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
- {
- if (e.PropertyName != nameof(CurveRecallChannelVM.IsDisplayed)) return;
- if (sender is not CurveRecallChannelVM channel) return;
-
- if (channel.IsDisplayed)
- {
- if (channel.Series != null && !Plot.Series.Contains(channel.Series))
- {
- Plot.Series.Add(channel.Series);
- }
- }
- else
- {
- if (channel.Series != null)
- {
- Plot.Series.Remove(channel.Series);
- }
- }
- Plot.InvalidatePlot(true);
- }
-
- private void ClearPlotAndChannels()
- {
- foreach (var ch in Channels)
- {
- ch.PropertyChanged -= OnChannelPropertyChanged;
- }
- Plot.Series.Clear();
- Channels.Clear();
- _colorIndex = 0;
- }
- #endregion
-
- #region 生命周期
- public override void OnNavigatedTo(NavigationContext navigationContext)
- {
- }
-
- public void Dispose()
- {
- ClearPlotAndChannels();
- }
- #endregion
- }
-
- ///
- /// CSV 监测记录(单行数据)。
- ///
- internal class MonitorRecord
- {
- public string MonitorName { get; set; } = string.Empty;
- public double MonitorValue { get; set; }
- public string Scope { get; set; } = string.Empty;
- public DateTime CreateTime { get; set; }
- }
-
- ///
- /// 曲线回读通道:MonitorName + Scope 唯一标识一条曲线。
- ///
- public class CurveRecallChannelVM : Prism.Mvvm.BindableBase
- {
- public string MonitorName { get; set; } = string.Empty;
- public string Scope { get; set; } = string.Empty;
- public string DisplayName { get; set; } = string.Empty;
- public OxyColor Color { get; set; } = OxyColors.SteelBlue;
-
- private bool _isDisplayed = true;
- public bool IsDisplayed
- {
- get => _isDisplayed;
- set => SetProperty(ref _isDisplayed, value);
- }
-
- public LineSeries? Series { get; set; }
- }
-}
diff --git a/MonitorModule/Views/CurveRecallView.xaml b/MonitorModule/Views/CurveRecallView.xaml
deleted file mode 100644
index b76de0f..0000000
--- a/MonitorModule/Views/CurveRecallView.xaml
+++ /dev/null
@@ -1,158 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/MonitorModule/Views/CurveRecallView.xaml.cs b/MonitorModule/Views/CurveRecallView.xaml.cs
deleted file mode 100644
index 8ba8774..0000000
--- a/MonitorModule/Views/CurveRecallView.xaml.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
-
-namespace MonitorModule.Views
-{
- ///
- /// CurveRecallView.xaml 的交互逻辑
- ///
- public partial class CurveRecallView : UserControl
- {
- public CurveRecallView()
- {
- InitializeComponent();
- }
- }
-}
diff --git a/ZLGUSBCANFD/USBCANFD.cs b/ZLGUSBCANFD/USBCANFD.cs
index 6208642..55f5034 100644
--- a/ZLGUSBCANFD/USBCANFD.cs
+++ b/ZLGUSBCANFD/USBCANFD.cs
@@ -358,18 +358,6 @@ namespace ZLGUSBCANFD
/// 0 = 只发送一次;>0 = 按指定间隔循环发送(毫秒)
/// 1 = CANFD,0 = CAN
/// 是否成功启动/发送
- public virtual bool 发送DBC定义报文(
- uint 通道号,
- uint 帧ID,
- Dictionary 信号物理值字典,
- int 循环间隔毫秒 = 0,
- int 是否使用CANFD = 1)
- {
- if (通道号 >= _maxChannels || _channelHandles[通道号] == IntPtr.Zero) return false;
- if (!_isDbcLoadedArray[通道号]) throw new InvalidOperationException($"通道 {通道号} 的 DBC 协议未加载,无法执行打包发送指令。");
- if (循环间隔毫秒 < 0) throw new ArgumentOutOfRangeException(nameof(循环间隔毫秒), "循环间隔必须大于或等于 0。");
- if (信号物理值字典 == null || 信号物理值字典.Count == 0)
- throw new ArgumentException("信号物理值字典不能为空。", nameof(信号物理值字典));
if (循环间隔毫秒 == 0)
{