From b21c1901e19a27359702747956d462a6772f5a30 Mon Sep 17 00:00:00 2001 From: hsc Date: Thu, 9 Jul 2026 11:34:03 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9B=91=E6=8E=A7=E9=85=8D=E7=BD=AE=E4=BF=9D?= =?UTF-8?q?=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DeviceEditModule/Views/IT7800EView.xaml | 46 +------ DeviceEditModule/Views/N36200View.xaml | 41 ------ MonitorModule/ViewModels/MonitorViewModel.cs | 126 ++++++++++++++++-- ...{MonitorViewView.xaml => MonitorView.xaml} | 4 + ...orViewView.xaml.cs => MonitorView.xaml.cs} | 0 UIShare/GlobalVariable/SystemConfig.cs | 6 + UIShare/UIShare.csproj | 1 + .../UIViewModel}/MonitorChannel.cs | 4 +- UIShare/UIViewModel/MonitorChannelConfig.cs | 17 +++ 9 files changed, 146 insertions(+), 99 deletions(-) rename MonitorModule/Views/{MonitorViewView.xaml => MonitorView.xaml} (98%) rename MonitorModule/Views/{MonitorViewView.xaml.cs => MonitorView.xaml.cs} (100%) rename {MonitorModule/ViewModels => UIShare/UIViewModel}/MonitorChannel.cs (97%) create mode 100644 UIShare/UIViewModel/MonitorChannelConfig.cs diff --git a/DeviceEditModule/Views/IT7800EView.xaml b/DeviceEditModule/Views/IT7800EView.xaml index e64e850..48a9778 100644 --- a/DeviceEditModule/Views/IT7800EView.xaml +++ b/DeviceEditModule/Views/IT7800EView.xaml @@ -13,51 +13,7 @@ - - - - - - - - - - - - - - + diff --git a/DeviceEditModule/Views/N36200View.xaml b/DeviceEditModule/Views/N36200View.xaml index cba29bc..9185c2e 100644 --- a/DeviceEditModule/Views/N36200View.xaml +++ b/DeviceEditModule/Views/N36200View.xaml @@ -12,47 +12,6 @@ - - - - - - - - - - diff --git a/MonitorModule/ViewModels/MonitorViewModel.cs b/MonitorModule/ViewModels/MonitorViewModel.cs index 6fea2e0..5fd15d4 100644 --- a/MonitorModule/ViewModels/MonitorViewModel.cs +++ b/MonitorModule/ViewModels/MonitorViewModel.cs @@ -1,6 +1,7 @@ using Common.Attributes; using Model.Entity; using Model.Models; +using NLog; using OxyPlot; using OxyPlot.Axes; using OxyPlot.Legends; @@ -19,6 +20,7 @@ using System.Windows.Input; using System.Windows.Threading; using UIShare.GlobalVariable; using UIShare.PubEvent; +using UIShare.UIViewModel; using UIShare.ViewModelBase; @@ -42,13 +44,25 @@ namespace MonitorModule.ViewModels public PlotModel Plot { get; } /// 已添加的监测通道列表 - public ObservableCollection Channels { get; } = new(); + public ObservableCollection Channels + { + get => _systemConfig?.Channels ?? new ObservableCollection(); + set + { + if (_systemConfig != null && _systemConfig.Channels != value) + { + _systemConfig.Channels = value; + RaisePropertyChanged(); + } + } + } + /// 可添加的设备方法列表(供用户选择) public ObservableCollection AvailableMethods { get; } = new(); - private MonitorChannel? _selectedChannel; - public MonitorChannel? SelectedChannel + private MonitorChannelVM? _selectedChannel; + public MonitorChannelVM? SelectedChannel { get => _selectedChannel; set => SetProperty(ref _selectedChannel, value); @@ -75,12 +89,14 @@ namespace MonitorModule.ViewModels public ICommand ResetViewCommand { get; } public ICommand RefreshDataCommand { get; } public ICommand RefreshCommand { get; } + public ICommand SaveCommand { get; } #endregion #region 私有字段 private bool IsInitiated = false; private IScopedProvider? _scope; private DeviceManager? _deviceManager; + private SystemConfig? _systemConfig; private CancellationTokenSource? _monitorCTS = new(); // 颜色调色盘 @@ -125,6 +141,7 @@ namespace MonitorModule.ViewModels ResetViewCommand = new DelegateCommand(OnResetView); RefreshDataCommand = new DelegateCommand(OnRefreshData); RefreshCommand = new DelegateCommand(OnExpand); + SaveCommand = new DelegateCommand(OnSave); // OxyPlot 刷新定时器(1000ms,只负责视觉更新) _plotRefreshTimer = new DispatcherTimer(DispatcherPriority.Background) @@ -134,6 +151,8 @@ namespace MonitorModule.ViewModels _plotRefreshTimer.Tick += OnPlotRefreshTick; } + + public void Dispose() { _monitorCTS?.Cancel(); @@ -159,7 +178,21 @@ namespace MonitorModule.ViewModels Channels.Clear(); AvailableMethods.Clear(); } - + private void OnSave() + { + // 将当前 Channels 序列化为 MonitorChannelConfig 列表保存到 MonitorChannels + if (_systemConfig != null) + { + _systemConfig.MonitorChannels = new ObservableCollection(Channels + .Select(c => new MonitorChannelConfig + { + Fingerprint = c.Fingerprint, + MethodName = c.MethodName, + IsDisplayed = c.IsDisplayed + })); + } + ConfigService.Save(_systemConfig); + } #region 事件驱动:接收广播数据 /// /// 由 HardwareDataBroadcaster 通过 EventAggregator 广播触发。 @@ -275,6 +308,8 @@ namespace MonitorModule.ViewModels _scope = _globalInfo.ScopeDic[TestStatus]; _scopedContext = _scope.Resolve(); _deviceManager = _scope.Resolve(); + _systemConfig = _scope.Resolve(); + RaisePropertyChanged(nameof(Channels)); _broadcaster = _scope.Resolve(); IsInitiated = true; @@ -286,15 +321,18 @@ namespace MonitorModule.ViewModels // 2. 扫描可监测方法(供 UI 选择) DiscoverAvailableMethods(); - // 3. 启动广播器(Discover + Start) + // 3. 从配置自动恢复已保存的监测通道 + RestoreChannelsFromConfig(); + + // 4. 启动广播器(Discover + Start) _broadcaster.Discover(); _broadcaster.Start(); - // 4. 订阅 HardwareDataReportedEvent(UI 线程回调) + // 5. 订阅 HardwareDataReportedEvent(UI 线程回调) _subscriptionToken = _eventAggregator.GetEvent() .Subscribe(OnHardwareDataReceived, ThreadOption.UIThread); - // 5. 启动 OxyPlot 视觉刷新定时器 + // 6. 启动 OxyPlot 视觉刷新定时器 _stopwatch.Start(); _plotRefreshTimer.Start(); } @@ -404,6 +442,72 @@ namespace MonitorModule.ViewModels ? $"发现 {AvailableMethods.Count} 个可监测项" : "未发现可监测的设备方法"; } + + /// + /// 从 SystemConfig.MonitorChannels 持久化列表自动还原监测通道。 + /// + private void RestoreChannelsFromConfig() + { + if (_systemConfig?.MonitorChannels == null || _systemConfig.MonitorChannels.Count == 0) return; + if (AvailableMethods.Count == 0) return; + + int restored = 0; + foreach (var config in _systemConfig.MonitorChannels) + { + if (string.IsNullOrWhiteSpace(config.Fingerprint) || + string.IsNullOrWhiteSpace(config.MethodName)) continue; + + // 已在 Channels 中存在则跳过 + if (Channels.Any(c => c.Fingerprint == config.Fingerprint && c.MethodName == config.MethodName)) + continue; + + // 在 AvailableMethods 中查找匹配项 + var method = AvailableMethods.FirstOrDefault(m => + m.Fingerprint == config.Fingerprint && m.MethodName == config.MethodName); + if (method == null) continue; + + var color = _palette[_colorIndex % _palette.Length]; + _colorIndex++; + + var channel = new MonitorChannelVM + { + DeviceName = method.DeviceName, + Fingerprint = method.Fingerprint, + MethodName = method.MethodName, + DisplayName = method.DisplayName, + Color = color, + IsMonitored = true, + IsDisplayed = config.IsDisplayed + }; + + // 仅当 IsDisplayed=true 时才创建 LineSeries + if (channel.IsDisplayed) + { + channel.Series = new LineSeries + { + Title = channel.DisplayName, + Color = color, + StrokeThickness = 1.5 + }; + Plot.Series.Add(channel.Series); + } + + channel.PropertyChanged += (s, e) => + { + if (e.PropertyName == nameof(MonitorChannelVM.IsDisplayed)) + OnChannelDisplayChanged(channel); + }; + + Channels.Add(channel); + restored++; + } + + if (restored > 0) + { + Plot.InvalidatePlot(true); + StatusMessage = $"已从配置自动恢复 {restored} 个监测通道"; + } + } #endregion #region 命令处理 @@ -426,7 +530,7 @@ namespace MonitorModule.ViewModels var color = _palette[_colorIndex % _palette.Length]; _colorIndex++; - var channel = new MonitorChannel + var channel = new MonitorChannelVM { DeviceName = method.DeviceName, Fingerprint = method.Fingerprint, @@ -447,7 +551,7 @@ namespace MonitorModule.ViewModels channel.PropertyChanged += (s, e) => { - if (e.PropertyName == nameof(MonitorChannel.IsDisplayed)) + if (e.PropertyName == nameof(MonitorChannelVM.IsDisplayed)) OnChannelDisplayChanged(channel); }; @@ -497,7 +601,7 @@ namespace MonitorModule.ViewModels #endregion #region 显示/隐藏切换与数学变换 - public void OnChannelDisplayChanged(MonitorChannel channel) + public void OnChannelDisplayChanged(MonitorChannelVM channel) { if (channel.IsDisplayed) { @@ -530,7 +634,7 @@ namespace MonitorModule.ViewModels } } - public void OnChannelMathChanged(MonitorChannel channel) + public void OnChannelMathChanged(MonitorChannelVM channel) { if (channel.Series == null) return; var points = channel.DataPoints.ToArray(); diff --git a/MonitorModule/Views/MonitorViewView.xaml b/MonitorModule/Views/MonitorView.xaml similarity index 98% rename from MonitorModule/Views/MonitorViewView.xaml rename to MonitorModule/Views/MonitorView.xaml index cc55bbc..f20f5ab 100644 --- a/MonitorModule/Views/MonitorViewView.xaml +++ b/MonitorModule/Views/MonitorView.xaml @@ -89,6 +89,10 @@ Command="{Binding RefreshDataCommand}" Padding="12,4" Margin="6,0,0,0" ToolTip="重新绘制图表"/> +