From 6c2b975999c73d9f1a123361e0f98c254c914d82 Mon Sep 17 00:00:00 2001 From: hsc Date: Mon, 6 Jul 2026 09:28:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8A=A5=E6=96=87=E8=AE=BE=E7=BD=AE=E6=89=A9?= =?UTF-8?q?=E5=B1=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ADP.sln | 7 + ADP/ADP.csproj | 1 + ADP/ViewModels/ShellViewModel.cs | 12 +- ADP/Views/ShellView.xaml | 10 + CANModule/CANModule.csproj | 14 ++ CANModule/UpdateInfoModule.cs | 17 ++ .../ViewModels/SelectCanMessageViewModel.cs | 171 ++++++++++++++++++ CANModule/Views/SelectCanMessageView.xaml | 69 +++++++ CANModule/Views/SelectCanMessageView.xaml.cs | 36 ++++ MonitorModule/ViewModels/MonitorViewModel.cs | 1 - ZLGUSBCANFD/USBCANFD.cs | 84 +++++++-- ZLGUSBCANFD/ZLGDBCParser.cs | 120 ++++++++++++ 12 files changed, 527 insertions(+), 15 deletions(-) create mode 100644 CANModule/CANModule.csproj create mode 100644 CANModule/UpdateInfoModule.cs create mode 100644 CANModule/ViewModels/SelectCanMessageViewModel.cs create mode 100644 CANModule/Views/SelectCanMessageView.xaml create mode 100644 CANModule/Views/SelectCanMessageView.xaml.cs create mode 100644 ZLGUSBCANFD/ZLGDBCParser.cs diff --git a/ADP.sln b/ADP.sln index 7cad4b3..cd8ee83 100644 --- a/ADP.sln +++ b/ADP.sln @@ -41,6 +41,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZLGUSBCANFD", "ZLGUSBCANFD\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchMovementModule", "BenchMovementModule\BenchMovementModule.csproj", "{31F84D0E-3634-4C70-A830-21AF412E3BBF}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CANModule", "CANModule\CANModule.csproj", "{AF2533DD-599D-49D7-942B-B0C26534D15F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -119,6 +121,10 @@ Global {31F84D0E-3634-4C70-A830-21AF412E3BBF}.Debug|Any CPU.Build.0 = Debug|Any CPU {31F84D0E-3634-4C70-A830-21AF412E3BBF}.Release|Any CPU.ActiveCfg = Release|Any CPU {31F84D0E-3634-4C70-A830-21AF412E3BBF}.Release|Any CPU.Build.0 = Release|Any CPU + {AF2533DD-599D-49D7-942B-B0C26534D15F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF2533DD-599D-49D7-942B-B0C26534D15F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF2533DD-599D-49D7-942B-B0C26534D15F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF2533DD-599D-49D7-942B-B0C26534D15F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -132,5 +138,6 @@ Global {850A5BE8-0BC1-4D6A-8351-DD812C9C4427} = {1E92D601-68FC-45F6-8251-BD0F39226E5B} {170AD4C1-189D-4FBE-B10D-2A4304527834} = {1E92D601-68FC-45F6-8251-BD0F39226E5B} {31F84D0E-3634-4C70-A830-21AF412E3BBF} = {1E92D601-68FC-45F6-8251-BD0F39226E5B} + {AF2533DD-599D-49D7-942B-B0C26534D15F} = {1E92D601-68FC-45F6-8251-BD0F39226E5B} EndGlobalSection EndGlobal diff --git a/ADP/ADP.csproj b/ADP/ADP.csproj index f525234..11e86a6 100644 --- a/ADP/ADP.csproj +++ b/ADP/ADP.csproj @@ -20,6 +20,7 @@ + diff --git a/ADP/ViewModels/ShellViewModel.cs b/ADP/ViewModels/ShellViewModel.cs index 7e86473..28128d6 100644 --- a/ADP/ViewModels/ShellViewModel.cs +++ b/ADP/ViewModels/ShellViewModel.cs @@ -29,6 +29,7 @@ namespace ADP.ViewModels private readonly IEventAggregator _eventAggregator; private readonly IRegionManager _regionManager; + private readonly IDialogService _dialogService; private readonly IContainerProvider _containerProvider; private readonly INotificationManager _notificationManager; private readonly IModuleManager _moduleManager; @@ -145,11 +146,13 @@ namespace ADP.ViewModels public ICommand NewCommand { get; set; } public ICommand SetDefaultCommand { get; set; } public ICommand ShowDialogManagerViewCommand { get; set; } + public ICommand SelectCANMessageCommand { get; set; } #endregion public ShellViewModel(IContainerProvider containerProvider) { _containerProvider = containerProvider; + _dialogService= containerProvider.Resolve(); _globalInfo = containerProvider.Resolve(); _eventAggregator = containerProvider.Resolve(); _regionManager = containerProvider.Resolve(); @@ -173,6 +176,7 @@ namespace ADP.ViewModels SaveAsCommand = new DelegateCommand(SaveAs); SaveCommand = new DelegateCommand(Save); SetDefaultCommand = new DelegateCommand(SetDefault); + SelectCANMessageCommand = new DelegateCommand(SelectCANMessage); _globalInfo.ContextDic.Add("default", new ScopedContext()); @@ -195,8 +199,7 @@ namespace ADP.ViewModels _uiRefreshTimer.Start(); } - - + private void RefreshAllContextProperties() { RaisePropertyChanged(nameof(RunState)); @@ -207,6 +210,11 @@ namespace ADP.ViewModels } #region 命令处理与事件 + private void SelectCANMessage() + { + _dialogService.ShowDialog("SelectCanMessageView"); + } + private void ShowDialogManagerView() { _eventAggregator.GetEvent().Publish(); diff --git a/ADP/Views/ShellView.xaml b/ADP/Views/ShellView.xaml index 5b8bfd2..0084fad 100644 --- a/ADP/Views/ShellView.xaml +++ b/ADP/Views/ShellView.xaml @@ -159,6 +159,16 @@ + + + + + + + + + + net8.0-windows + enable + true + enable + + + + + + + diff --git a/CANModule/UpdateInfoModule.cs b/CANModule/UpdateInfoModule.cs new file mode 100644 index 0000000..aa035ac --- /dev/null +++ b/CANModule/UpdateInfoModule.cs @@ -0,0 +1,17 @@ +using System.Reflection; +using CANModule.Views; + +namespace CANModule +{ + public class CANModule : IModule + { + public void OnInitialized(IContainerProvider containerProvider) + { + } + + public void RegisterTypes(IContainerRegistry containerRegistry) + { + containerRegistry.RegisterDialog("SelectCanMessageView"); + } + } +} diff --git a/CANModule/ViewModels/SelectCanMessageViewModel.cs b/CANModule/ViewModels/SelectCanMessageViewModel.cs new file mode 100644 index 0000000..5a98bbb --- /dev/null +++ b/CANModule/ViewModels/SelectCanMessageViewModel.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections.ObjectModel; +using System.Linq; +using System.Windows; +using System.Windows.Input; +using UIShare.ViewModelBase; +using ZLGUSBCANFD; + +namespace CANModule.ViewModels +{ + public class SelectCanMessageViewModel : DialogViewModelBase + { + #region 属性 + public DialogCloseListener RequestClose { get; set; } + + private ObservableCollection _ChannelList; + public ObservableCollection ChannelList + { + get => _ChannelList; + set => SetProperty(ref _ChannelList, value); + } + + private ObservableCollection _messageList; + public ObservableCollection MessageList + { + get => _messageList; + set => SetProperty(ref _messageList, value); + } + + private ObservableCollection _signalList; + public ObservableCollection SignalList + { + get => _signalList; + set => SetProperty(ref _signalList, value); + } + + private string _title = "CollectCANSignalSetting"; + public string Title + { + get => _title; + set => SetProperty(ref _title, value); + } + + private string _selectedMessage; + public string SelectedMessage + { + get => _selectedMessage; + set + { + if (SetProperty(ref _selectedMessage, value)) + { + // 健壮性检查:防范切换通道时清空选择引发的连锁 Bug + if (!string.IsNullOrEmpty(value)) + { + // 使用 FirstOrDefault 代替 First,防止找不到匹配项时导致上位机崩溃 + var targetMsg = ZLGDBCParser.MsgDatabase[MessageChannel] + .FirstOrDefault(x => $"[0x{x.msg_id:X}]{x.msg_name}" == value); + + if (targetMsg != null && targetMsg.signal_Name != null) + { + SignalList = new ObservableCollection(targetMsg.signal_Name); + } + else + { + SignalList = new ObservableCollection(); + } + } + else + { + SignalList = new ObservableCollection(); + } + } + } + } + + private string _selectedSignal; + public string SelectedSignal + { + get => _selectedSignal; + set => SetProperty(ref _selectedSignal, value); + } + + private int _MessageChannel=-1; + public int MessageChannel + { + get => _MessageChannel; + set + { + if (_MessageChannel != value) + { + _MessageChannel = value; + + // 1. 先安全清空旧的选择项和信号列表,断开引用链 + SelectedMessage = null; + SelectedSignal = null; + SignalList = new ObservableCollection(); + + // 2. 刷新当前通道的报文列表 + if (ZLGDBCParser.MsgDatabase != null && ZLGDBCParser.MsgDatabase.Count > value) + { + MessageList = new ObservableCollection( + ZLGDBCParser.MsgDatabase[value].Select(s => $"[0x{s.msg_id:X}]{s.msg_name}") + ); + } + else + { + MessageList = new ObservableCollection(); + } + + RaisePropertyChanged(); + } + } + } + #endregion + + #region 命令 + public ICommand CloseCommand { get; set; } + public ICommand GetSelectedMessageCommand { get; set; } + public ICommand GetSelectedSignalCommand { get; set; } + public ICommand LoadCommand { get; set; } + #endregion + + public SelectCanMessageViewModel(IContainerProvider containerProvider) : base(containerProvider) + { + CloseCommand = new DelegateCommand(Close); + GetSelectedMessageCommand = new DelegateCommand(GetSelectedMessage); + GetSelectedSignalCommand = new DelegateCommand(GetSelectedSignal); + LoadCommand = new DelegateCommand(Load); + } + + #region 命令处理 + private void Close() + { + RequestClose.Invoke(); + } + + private void Load() + { + ChannelList = new ObservableCollection(Enumerable.Range(0, 4)); + } + + private void GetSelectedSignal() + { + if (!string.IsNullOrEmpty(SelectedSignal)) + { + Application.Current.Dispatcher.Invoke(() => + { + Clipboard.SetDataObject(SelectedSignal); + }); + } + } + + private void GetSelectedMessage() + { + // 修复原本误写为 SelectedSignal != null 的 Bug,并增加了边界防错 + if (!string.IsNullOrEmpty(SelectedMessage) && SelectedMessage.Contains(']')) + { + Application.Current.Dispatcher.Invoke(() => + { + Clipboard.SetDataObject(SelectedMessage); + //var parts = SelectedMessage.Split(']'); + //if (parts.Length > 1) + //{ + // Clipboard.SetDataObject(parts[1]); // 复制纯报文名称(如:"EngineStatus") + //} + }); + } + } + #endregion + } +} \ No newline at end of file diff --git a/CANModule/Views/SelectCanMessageView.xaml b/CANModule/Views/SelectCanMessageView.xaml new file mode 100644 index 0000000..9edee97 --- /dev/null +++ b/CANModule/Views/SelectCanMessageView.xaml @@ -0,0 +1,69 @@ + + +