From bb4fe61ded665d562764bcc19a758ff9fc49fb49 Mon Sep 17 00:00:00 2001 From: czj Date: Fri, 5 Jun 2026 14:29:22 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=9C=E7=94=A8=E5=9F=9F=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewModels/AutomatedTestingViewModel.cs | 4 +- MonitorModule/ViewModels/MonitorViewModel.cs | 105 +++++++++--------- MonitorModule/ViewModels/RecordViewModel.cs | 63 +++++------ SettingModule/ViewModels/SettingViewModel.cs | 84 ++++++++------ UIShare/GlobalVariable/GlobalInfo.cs | 2 + 5 files changed, 131 insertions(+), 127 deletions(-) diff --git a/MainModule/ViewModels/AutomatedTestingViewModel.cs b/MainModule/ViewModels/AutomatedTestingViewModel.cs index d7dbbaa..043837e 100644 --- a/MainModule/ViewModels/AutomatedTestingViewModel.cs +++ b/MainModule/ViewModels/AutomatedTestingViewModel.cs @@ -86,8 +86,9 @@ namespace MainModule.ViewModels private void OnRefresh() { // 双击:把自己的名字扔出去 - _eventAggregator.GetEvent().Publish(TestStatus); _globalInfo.CurrentScope = TestStatus; + _eventAggregator.GetEvent().Publish(TestStatus); + } private void OnBackToProtocol() @@ -106,6 +107,7 @@ namespace MainModule.ViewModels TestStatus = navigationContext.Parameters.GetValue("Name"); _globalInfo.ContextDic.Add(TestStatus, _scopedContext); _globalInfo.StepRunningDic.Add(TestStatus, _stepRunning); + _globalInfo.ScopeDic.Add(TestStatus, _scope); } } diff --git a/MonitorModule/ViewModels/MonitorViewModel.cs b/MonitorModule/ViewModels/MonitorViewModel.cs index f04732b..b957059 100644 --- a/MonitorModule/ViewModels/MonitorViewModel.cs +++ b/MonitorModule/ViewModels/MonitorViewModel.cs @@ -21,15 +21,53 @@ namespace MonitorModule.ViewModels /// public class MonitorViewModel : NavigateViewModelBase, IRegionMemberLifetime, IDisposable { + #region 属性 + public bool KeepAlive => true; + public ScopedContext _scopedContext { get; set; } + public GlobalInfo _globalInfo { get; set; } + + public string TestStatus + { + get => _testStatus; + set => SetProperty(ref _testStatus, value); + } + + /// PlotView 直接绑这个 PlotModel + public PlotModel Plot { get; } + + /// 当前已添加的信号集合(左侧列表展示) + public ObservableCollection Signals { get; } = new(); + + public SignalItem? SelectedSignal + { + get => _selectedSignal; + set => SetProperty(ref _selectedSignal, value); + } + + public string StatusMessage + { + get => _statusMessage; + set => SetProperty(ref _statusMessage, value); + } + #endregion + #region 命令 + public ICommand AddSignalCommand { get; } + public ICommand DeleteSignalCommand { get; } + public ICommand ResetViewCommand { get; } + public ICommand RefreshDataCommand { get; } + // 双击展开/折叠:与 RecordView/AutomatedTestingView 共用同一套 ExpandViewEvent + public ICommand RefreshCommand { get; } + #endregion #region 私有字段 - private readonly IScopedProvider _scope; + private bool IsInitiated = false; + private IScopedProvider _scope; // 颜色轮转池,给新加的信号自动分配区分色 private static readonly OxyColor[] _palette = { - OxyColors.SteelBlue, OxyColors.IndianRed, OxyColors.SeaGreen, - OxyColors.DarkOrange, OxyColors.MediumPurple, OxyColors.Goldenrod, - OxyColors.Teal, OxyColors.Crimson, OxyColors.OliveDrab - }; + OxyColors.SteelBlue, OxyColors.IndianRed, OxyColors.SeaGreen, + OxyColors.DarkOrange, OxyColors.MediumPurple, OxyColors.Goldenrod, + OxyColors.Teal, OxyColors.Crimson, OxyColors.OliveDrab +}; private int _signalCounter; // ===== 模拟数据相关 ===== @@ -43,60 +81,15 @@ namespace MonitorModule.ViewModels private const int _maxPoints = 200; // 用于 random walk 的随机源 private static readonly Random _rng = new(); - #endregion - - #region 隔离 / 标题 - public bool KeepAlive => true; - public ScopedContext _scopedContext { get; } - public GlobalInfo GlobalInfoRef { get; } - private string _testStatus = string.Empty; - public string TestStatus - { - get => _testStatus; - set => SetProperty(ref _testStatus, value); - } - #endregion - - #region OxyPlot - /// PlotView 直接绑这个 PlotModel - public PlotModel Plot { get; } - - /// 当前已添加的信号集合(左侧列表展示) - public ObservableCollection Signals { get; } = new(); - private SignalItem? _selectedSignal; - public SignalItem? SelectedSignal - { - get => _selectedSignal; - set => SetProperty(ref _selectedSignal, value); - } - private string _statusMessage = "图表已就绪,暂无信号"; - public string StatusMessage - { - get => _statusMessage; - set => SetProperty(ref _statusMessage, value); - } - #endregion - - #region 命令 - public ICommand AddSignalCommand { get; } - public ICommand DeleteSignalCommand { get; } - public ICommand ResetViewCommand { get; } - public ICommand RefreshDataCommand { get; } - // 双击展开/折叠:与 RecordView/AutomatedTestingView 共用同一套 ExpandViewEvent - public ICommand RefreshCommand { get; } #endregion public MonitorViewModel(IContainerExtension container) : base(container) { - _scope = container.CreateScope(); - GlobalInfoRef = container.Resolve(); - _scopedContext = _scope.Resolve(); - + _globalInfo = container.Resolve(); Plot = BuildEmptyPlot(); - AddSignalCommand = new DelegateCommand(OnAddSignal); DeleteSignalCommand = new DelegateCommand(OnDeleteSignal); ResetViewCommand = new DelegateCommand(OnResetView); @@ -257,8 +250,9 @@ namespace MonitorModule.ViewModels private void OnExpand() { if (string.IsNullOrEmpty(TestStatus)) return; + _globalInfo.CurrentScope = TestStatus; _eventAggregator.GetEvent().Publish(TestStatus); - GlobalInfoRef.CurrentScope = TestStatus; + } /// @@ -297,15 +291,18 @@ namespace MonitorModule.ViewModels } #endregion - #region 导航 + #region 重写 public override void OnNavigatedTo(NavigationContext navigationContext) { base.OnNavigatedTo(navigationContext); - if (navigationContext.Parameters.ContainsKey("Name")) + if (!IsInitiated && navigationContext.Parameters.ContainsKey("Name")) { TestStatus = navigationContext.Parameters.GetValue("Name"); Plot.Title = $"监控 - {TestStatus}"; Plot.InvalidatePlot(false); + _scope = _globalInfo.ScopeDic[TestStatus]; + _scopedContext = _globalInfo.ContextDic[TestStatus]; + IsInitiated = true; } } #endregion diff --git a/MonitorModule/ViewModels/RecordViewModel.cs b/MonitorModule/ViewModels/RecordViewModel.cs index d11bf99..cd2c86d 100644 --- a/MonitorModule/ViewModels/RecordViewModel.cs +++ b/MonitorModule/ViewModels/RecordViewModel.cs @@ -18,40 +18,24 @@ namespace MonitorModule.ViewModels /// public class RecordViewModel : NavigateViewModelBase, IRegionMemberLifetime, IDisposable { - #region 私有字段 - // 数据库相对路径:运行目录\SQL\ADP.db(数据库未就绪时容错处理,不抛异常) - private static readonly string DbFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SQL"); - private static readonly string DbPath = Path.Combine(DbFolder, "ADP.db"); - private static readonly string ConnStr = $"Data Source={DbPath};Version=3;"; - private readonly IScopedProvider _scope; - #endregion - - #region 隔离演示属性(保留 ScopedContext 验证用) + #region 属性 public bool KeepAlive => true; - public ScopedContext _scopedContext { get; } - // 公开一份 GlobalInfo 供双击展开逻辑使用(基类的 _globalInfo 是 private) - public GlobalInfo GlobalInfoRef { get; } - #endregion + public ScopedContext _scopedContext { get; set; } + public GlobalInfo _globalInfo { get; } - #region 顶部工位标题 - private string _testStatus = string.Empty; public string TestStatus { get => _testStatus; set => SetProperty(ref _testStatus, value); } - #endregion - #region 数据库 / 表 / 查询条件 - private ObservableCollection _tableNames = new(); public ObservableCollection TableNames { get => _tableNames; set => SetProperty(ref _tableNames, value); } - private string? _selectedTable; public string? SelectedTable { get => _selectedTable; @@ -66,37 +50,30 @@ namespace MonitorModule.ViewModels } // 用户填写的 WHERE 子句(不带 WHERE 关键字),例如:Status='OK' AND Id>10 - private string _whereClause = string.Empty; public string WhereClause { get => _whereClause; set => SetProperty(ref _whereClause, value); } - private DataTable _resultTable = new(); public DataTable ResultTable { get => _resultTable; set => SetProperty(ref _resultTable, value); } - private string _statusMessage = "未连接"; public string StatusMessage { get => _statusMessage; set => SetProperty(ref _statusMessage, value); } - #endregion - #region 分页 - private int _pageIndex = 1; public int PageIndex { get => _pageIndex; set => SetProperty(ref _pageIndex, value); } - private int _pageSize = 50; public int PageSize { get => _pageSize; @@ -111,7 +88,6 @@ namespace MonitorModule.ViewModels } } - private long _totalCount; public long TotalCount { get => _totalCount; @@ -145,13 +121,27 @@ namespace MonitorModule.ViewModels // 双击展开/折叠:与 MonitorView/AutomatedTestingView 共用 public ICommand RefreshCommand { get; } #endregion + #region 私有字段 + // 数据库相对路径:运行目录\SQL\ADP.db(数据库未就绪时容错处理,不抛异常) + private static readonly string DbFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SQL"); + private static readonly string DbPath = Path.Combine(DbFolder, "ADP.db"); + private static readonly string ConnStr = $"Data Source={DbPath};Version=3;"; + private bool IsInitiated = false; + private IScopedProvider _scope; + private string _testStatus = string.Empty; + private ObservableCollection _tableNames = new(); + private string? _selectedTable; + private string _whereClause = string.Empty; + private DataTable _resultTable = new(); + private string _statusMessage = "未连接"; + private int _pageIndex = 1; + private int _pageSize = 50; + private long _totalCount; + #endregion public RecordViewModel(IContainerExtension container) : base(container) { - _scope = container.CreateScope(); - GlobalInfoRef = container.Resolve(); - _scopedContext = _scope.Resolve(); - + _globalInfo = container.Resolve(); LoadedCommand = new DelegateCommand(LoadTables); RefreshTablesCommand = new DelegateCommand(LoadTables); QueryCommand = new DelegateCommand(() => { PageIndex = 1; Query(); }); @@ -341,20 +331,23 @@ namespace MonitorModule.ViewModels private void OnExpand() { if (string.IsNullOrEmpty(TestStatus)) return; + _globalInfo.CurrentScope = TestStatus; _eventAggregator.GetEvent().Publish(TestStatus); - GlobalInfoRef.CurrentScope = TestStatus; + } #endregion - #region 导航 + #region 重写 public override void OnNavigatedTo(NavigationContext navigationContext) { base.OnNavigatedTo(navigationContext); - if (navigationContext.Parameters.ContainsKey("Name")) + if (!IsInitiated&&navigationContext.Parameters.ContainsKey("Name")) { TestStatus = navigationContext.Parameters.GetValue("Name"); + _scope = _globalInfo.ScopeDic[TestStatus]; + _scopedContext = _globalInfo.ContextDic[TestStatus]; + IsInitiated = true; } - // 进入界面时自动加载表 LoadTables(); } #endregion diff --git a/SettingModule/ViewModels/SettingViewModel.cs b/SettingModule/ViewModels/SettingViewModel.cs index 08de9f9..d370cda 100644 --- a/SettingModule/ViewModels/SettingViewModel.cs +++ b/SettingModule/ViewModels/SettingViewModel.cs @@ -1,23 +1,27 @@ using System; using System.Collections.ObjectModel; using System.Windows.Input; +using Prism.Commands; +using Prism.Ioc; using UIShare.GlobalVariable; using UIShare.PubEvent; using UIShare.UIViewModel; using UIShare.ViewModelBase; + namespace SettingModule.ViewModels { public class SettingViewModel : NavigateViewModelBase, IRegionMemberLifetime, IDisposable { + #region 属性 public bool KeepAlive => true; - private string _testStatus = string.Empty; + public string TestStatus { get => _testStatus; set => SetProperty(ref _testStatus, value); } - private DeviceInfoModel? _selectedDevice; + public DeviceInfoModel? SelectedDevice { get => _selectedDevice; @@ -29,26 +33,23 @@ namespace SettingModule.ViewModels } } } - private ObservableCollection _deviceList; public ObservableCollection DeviceList { - get { return _deviceList; } - set { SetProperty(ref _deviceList,value); } + get => _deviceList; + set => SetProperty(ref _deviceList, value); } - private string _statusMessage = "请在左侧选择设备查看 / 编辑配置"; + public string StatusMessage { get => _statusMessage; set => SetProperty(ref _statusMessage, value); } - #endregion - #region 私有字段 - private readonly IScopedProvider _scope; - private readonly SystemConfig _systemConfig; - private ScopedContext _scopedContext { get; } - private GlobalInfo GlobalInfoRef { get; } + public ObservableCollection ConnectionTypes { get; } = new() + { + "None", "TCP", "Serial" + }; #endregion #region 命令 @@ -57,32 +58,25 @@ namespace SettingModule.ViewModels public ICommand ResetCommand { get; } public ICommand OpenConnectionConfigCommand { get; } #endregion - - public ObservableCollection ConnectionTypes { get; } = new() - { - "None", "TCP", "Serial" - }; - + #region 私有字段 + private IScopedProvider _scope; + private SystemConfig _systemConfig; + private ScopedContext _scopedContext { get; set; } + private GlobalInfo _globalInfo { get; } + private bool IsInitiated = false; + private string _testStatus = string.Empty; + private DeviceInfoModel? _selectedDevice; + private ObservableCollection _deviceList; + private string _statusMessage = "请在左侧选择设备查看 / 编辑配置"; + #endregion public SettingViewModel(IContainerExtension container) : base(container) { - _scope = container.CreateScope(); - GlobalInfoRef = container.Resolve(); - _scopedContext = _scope.Resolve(); - _systemConfig = _scope.Resolve(); - - // 直接复用 SystemConfig 的 DeviceList,外部修改可同步反映 - DeviceList = _systemConfig.DeviceList; + _globalInfo = container.Resolve(); RefreshCommand = new DelegateCommand(OnExpand); SaveCommand = new DelegateCommand(OnSave); ResetCommand = new DelegateCommand(OnReset); OpenConnectionConfigCommand = new DelegateCommand(OnOpenConnectionConfig); - - // 进来默认选中第一个,让右侧不为空 - if (DeviceList.Count > 0) - { - SelectedDevice = DeviceList[0]; - } } public void Dispose() @@ -90,7 +84,7 @@ namespace SettingModule.ViewModels _scope?.Dispose(); } - #region 命令处理 + #region 命令 /// /// 选中设备切换:右侧配置面板靠 SelectedDevice 绑定自动刷新, /// 这里只负责更新状态栏提示。 @@ -109,8 +103,8 @@ namespace SettingModule.ViewModels private void OnExpand() { if (string.IsNullOrEmpty(TestStatus)) return; + _globalInfo.CurrentScope = TestStatus; _eventAggregator.GetEvent().Publish(TestStatus); - GlobalInfoRef.CurrentScope = TestStatus; } /// 保存当前选中设备的配置(占位,实际写盘逻辑后续接入)。 @@ -159,7 +153,13 @@ namespace SettingModule.ViewModels return; } - var p = new DialogParameters { { "Device", SelectedDevice } }; + // 【关键修改】在此处将选中的设备以及隔离作用域内的 _systemConfig 一并传进弹窗 + var p = new DialogParameters + { + { "Device", SelectedDevice }, + { "SystemConfig", _systemConfig } + }; + _dialogService.ShowDialog(dialogName, p, r => { if (r.Result == ButtonResult.OK) @@ -170,15 +170,25 @@ namespace SettingModule.ViewModels } #endregion - #region 导航 + #region 重写 public override void OnNavigatedTo(NavigationContext navigationContext) { base.OnNavigatedTo(navigationContext); - if (navigationContext.Parameters.ContainsKey("Name")) + if (!IsInitiated && navigationContext.Parameters.ContainsKey("Name")) { TestStatus = navigationContext.Parameters.GetValue("Name"); + _scope = _globalInfo.ScopeDic[TestStatus]; + _scopedContext = _globalInfo.ContextDic[TestStatus]; + _systemConfig = _scope.Resolve(); + DeviceList = _systemConfig.DeviceList; + if (DeviceList != null && DeviceList.Count > 0) + { + SelectedDevice = DeviceList[0]; + } + + IsInitiated = true; } } #endregion } -} +} \ No newline at end of file diff --git a/UIShare/GlobalVariable/GlobalInfo.cs b/UIShare/GlobalVariable/GlobalInfo.cs index 071de06..bc6ee93 100644 --- a/UIShare/GlobalVariable/GlobalInfo.cs +++ b/UIShare/GlobalVariable/GlobalInfo.cs @@ -11,6 +11,7 @@ namespace UIShare.GlobalVariable public event EventHandler? ScopeChanged; public Dictionary ContextDic { get; set; } public Dictionary StepRunningDic { get; set; } + public Dictionary ScopeDic { get; set; } public String UserName { get; set; } = "Not Logged in"; public bool IsAdmin { get; set; } = true; private string _currentScope = "default"; @@ -30,6 +31,7 @@ namespace UIShare.GlobalVariable { ContextDic = new(); StepRunningDic = new(); + ScopeDic = new(); CurrentScope = "default"; }