using AutoMapper; using CapMachine.Core; using CapMachine.Model.CANLIN; using CapMachine.Wpf.Dtos; using CapMachine.Wpf.LinDrive; using CapMachine.Wpf.Services; using CapMachine.Wpf.Views; using ImTools; using Microsoft.Win32; using Prism.Commands; using Prism.Events; using Prism.Regions; using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Windows; using System.Windows.Controls; using static CapMachine.Wpf.Models.ComEnum; namespace CapMachine.Wpf.ViewModels { /// /// ZLG LIN 配置 ViewModel。 /// public class ZlgLinDriveConfigViewModel : NavigationViewModel { /// /// 构造函数。 /// public ZlgLinDriveConfigViewModel(IDialogService dialogService, IFreeSql freeSql, IEventAggregator eventAggregator, IRegionManager regionManager, SysRunService sysRunService, ConfigService configService, ZlgLinDriveService zlgLinDriveService, ZlgCanDriveService zlgCanDriveService, ComActionService comActionService, LogicRuleService logicRuleService, IMapper mapper) { DialogService = dialogService; FreeSql = freeSql; EventAggregator = eventAggregator; RegionManager = regionManager; SysRunService = sysRunService; ConfigService = configService; ZlgLinDriveService = zlgLinDriveService; ZlgCanDriveService = zlgCanDriveService; ComActionService = comActionService; LogicRuleService = logicRuleService; Mapper = mapper; InitLoadLinConfigPro(); } public IDialogService DialogService { get; } public IFreeSql FreeSql { get; } public IEventAggregator EventAggregator { get; } public IRegionManager RegionManager { get; } public SysRunService SysRunService { get; } public ConfigService ConfigService { get; } public ZlgLinDriveService ZlgLinDriveService { get; } public ZlgCanDriveService ZlgCanDriveService { get; } public ComActionService ComActionService { get; } public LogicRuleService LogicRuleService { get; } public IMapper Mapper { get; } private List linConfigPros = new List(); private ObservableCollection? _ListCanLinConfigPro; /// /// LIN 配置程序集合。 /// public ObservableCollection? ListCanLinConfigPro { get { return _ListCanLinConfigPro; } set { _ListCanLinConfigPro = value; RaisePropertyChanged(); } } /// /// 选中的配置程序。 /// public CanLinConfigPro? SelectCanLinConfigPro { get; set; } private ObservableCollection _listWriteCanLinRWConfigDto = new ObservableCollection(); public ObservableCollection ListWriteCanLinRWConfigDto { get { return _listWriteCanLinRWConfigDto; } set { _listWriteCanLinRWConfigDto = value; RaisePropertyChanged(); } } private ObservableCollection _listReadCanLinRWConfigDto = new ObservableCollection(); public ObservableCollection ListReadCanLinRWConfigDto { get { return _listReadCanLinRWConfigDto; } set { _listReadCanLinRWConfigDto = value; RaisePropertyChanged(); } } public bool IsRwEditable { get { return !ZlgLinDriveService.OpenState; } } private LINConfigExdDto? _SelectedLINConfigExdDto; /// /// 选中的 LIN 配置 DTO。 /// public LINConfigExdDto? SelectedLINConfigExdDto { get { return _SelectedLINConfigExdDto; } set { _SelectedLINConfigExdDto = value; RaisePropertyChanged(); RaisePropertyChanged(nameof(CurrentLdfPath)); RaisePropertyChanged(nameof(CurrentSchEnable)); RaisePropertyChanged(nameof(LinBaudRate)); } } /// /// 当前 LDF 路径。 /// public string? CurrentLdfPath { get { return SelectedLINConfigExdDto?.LdfPath; } set { if (SelectedLINConfigExdDto == null) return; SelectedLINConfigExdDto.LdfPath = value; RaisePropertyChanged(); } } /// /// LIN 波特率。 /// public int LinBaudRate { get { return SelectedLINConfigExdDto?.BaudRate ?? 0; } set { if (SelectedLINConfigExdDto == null) return; SelectedLINConfigExdDto.BaudRate = value; RaisePropertyChanged(); } } /// /// 调度表使能。 /// public bool CurrentSchEnable { get { return SelectedLINConfigExdDto?.SchEnable ?? false; } set { if (SelectedLINConfigExdDto == null) return; SelectedLINConfigExdDto.SchEnable = value; RaisePropertyChanged(); } } private void InitLoadLinConfigPro() { linConfigPros = FreeSql.Select() .Where(a => a.CANLINInfo == CANLIN.LIN) .Include(a => a.LINConfigExd) .IncludeMany(a => a.CanLinConfigContents, then => then.Include(b => b.LogicRule)) .IncludeMany(a => a.LinScheduleConfigs) .ToList(); ListCanLinConfigPro = new ObservableCollection(linConfigPros); } private void SyncSelectedConfig() { if (SelectCanLinConfigPro == null) return; SelectedLINConfigExdDto = Mapper.Map(SelectCanLinConfigPro.LINConfigExd); var writeData = SelectCanLinConfigPro.CanLinConfigContents?.Where(a => a.RWInfo == RW.Write).ToList() ?? new List(); ListWriteCanLinRWConfigDto = new ObservableCollection(Mapper.Map>(writeData)); var readData = SelectCanLinConfigPro.CanLinConfigContents?.Where(a => a.RWInfo == RW.Read).ToList() ?? new List(); ListReadCanLinRWConfigDto = new ObservableCollection(Mapper.Map>(readData)); RaisePropertyChanged(nameof(IsRwEditable)); } private DelegateCommand? _LinConfigProGridSelectionChangedCmd; /// /// LIN 配置程序选中变化。 /// public DelegateCommand LinConfigProGridSelectionChangedCmd { get { if (_LinConfigProGridSelectionChangedCmd == null) { _LinConfigProGridSelectionChangedCmd = new DelegateCommand(LinConfigProGridSelectionChangedCmdMethod); } return _LinConfigProGridSelectionChangedCmd; } } private void LinConfigProGridSelectionChangedCmdMethod(object par) { if (par == null) return; if (par is SelectionChangedEventArgs) return; if (par is CanLinConfigPro) { SelectCanLinConfigPro = par as CanLinConfigPro; SyncSelectedConfig(); return; } var args = par as SelectionChangedEventArgs; if (args == null || args.AddedItems == null || args.AddedItems.Count == 0) return; var selected = args.AddedItems[0] as CanLinConfigPro; if (selected == null) return; SelectCanLinConfigPro = selected; SyncSelectedConfig(); } private DelegateCommand? _LoadLdfCmd; /// /// 选择 LDF 文件。 /// public DelegateCommand LoadLdfCmd { get { if (_LoadLdfCmd == null) { _LoadLdfCmd = new DelegateCommand(LoadLdfCmdMethod); } return _LoadLdfCmd; } } private void LoadLdfCmdMethod() { try { if (SelectCanLinConfigPro == null || SelectedLINConfigExdDto == null) { MessageBox.Show("选中LIN配置名称后再操作", "提示", MessageBoxButton.OK, MessageBoxImage.Hand); return; } OpenFileDialog openFileDialogInfo = new OpenFileDialog(); openFileDialogInfo.Filter = "(*.ldf;*.ldf)|*.ldf;*.ldf|all|*.*"; openFileDialogInfo.CheckFileExists = true; openFileDialogInfo.CheckPathExists = true; openFileDialogInfo.ShowDialog(); CurrentLdfPath = openFileDialogInfo.FileName; } catch { MessageBox.Show("可能未选择信息", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Hand); } } private DelegateCommand? _LinOpCmd; /// /// LIN 操作命令。 /// public DelegateCommand LinOpCmd { get { if (_LinOpCmd == null) { _LinOpCmd = new DelegateCommand(LinOpCmdMethod); } return _LinOpCmd; } } private void LinOpCmdMethod(string par) { switch (par) { case "Open": if (ComActionService.IsLINToDoWork() == false) { MessageBox.Show("请关闭CAN连接后才能开启LIN,同一个时刻只能有一个通信驱动压缩机", "提示", MessageBoxButton.OK, MessageBoxImage.Hand); return; } if (ZlgCanDriveService.OpenState) { MessageBox.Show("请先关闭 ZLG CAN 连接后再开启 ZLG LIN", "提示", MessageBoxButton.OK, MessageBoxImage.Hand); return; } if (SelectCanLinConfigPro == null || SelectedLINConfigExdDto == null) { MessageBox.Show("选中LIN配置名称后再操作", "提示", MessageBoxButton.OK, MessageBoxImage.Hand); return; } // 打开 LIN(不依赖 LDF) ZlgLinDriveService.StartLinDrive(0, (uint)SelectedLINConfigExdDto.BaudRate, isMaster: true); if (ZlgLinDriveService.OpenState) { ConfigService.CanLinRunStateModel.CurSysSelectedCanLin = CanLinEnum.Lin; } RaisePropertyChanged(nameof(IsRwEditable)); break; case "Close": ZlgLinDriveService.CloseDevice(); ConfigService.CanLinRunStateModel.CurSysSelectedCanLin = CanLinEnum.No; RaisePropertyChanged(nameof(IsRwEditable)); break; case "Save": if (SelectCanLinConfigPro == null || SelectedLINConfigExdDto == null) { MessageBox.Show("选中LIN配置名称后再操作", "提示", MessageBoxButton.OK, MessageBoxImage.Hand); return; } FreeSql.Update() .Set(a => a.LdfPath, SelectedLINConfigExdDto.LdfPath) .Set(a => a.Cycle, SelectedLINConfigExdDto.Cycle) .Set(a => a.BaudRate, SelectedLINConfigExdDto.BaudRate) .Set(a => a.SchEnable, SelectedLINConfigExdDto.SchEnable) .Where(a => a.Id == SelectedLINConfigExdDto.Id) .ExecuteUpdated(); InitLoadLinConfigPro(); break; case "Parse": // 明确提示:当前 ZLG LIN 暂不支持 LDF if (SelectCanLinConfigPro == null || SelectedLINConfigExdDto == null) { MessageBox.Show("选中LIN配置名称后再操作", "提示", MessageBoxButton.OK, MessageBoxImage.Hand); return; } try { ZlgLinDriveService.StartLdf(SelectedLINConfigExdDto.LdfPath ?? string.Empty); } catch (Exception ex) { MessageBox.Show(ex.Message, "提示", MessageBoxButton.OK, MessageBoxImage.Hand); } break; } } private DelegateCommand? _openRwDialogCmd; public DelegateCommand OpenRwDialogCmd { get { if (_openRwDialogCmd == null) { _openRwDialogCmd = new DelegateCommand(OpenRwDialogCmdMethod); } return _openRwDialogCmd; } } private void OpenRwDialogCmdMethod() { try { if (SelectCanLinConfigPro == null) { MessageBox.Show("选中LIN配置名称后再操作", "提示", MessageBoxButton.OK, MessageBoxImage.Hand); return; } var writeClones = new ObservableCollection( (ListWriteCanLinRWConfigDto ?? new ObservableCollection()) .Select(CloneRwDto)); foreach (var item in writeClones) { item.RWInfo = RW.Write; } var readClones = new ObservableCollection( (ListReadCanLinRWConfigDto ?? new ObservableCollection()) .Select(CloneRwDto)); foreach (var item in readClones) { item.RWInfo = RW.Read; } var candidates = new ObservableCollection(); if (ZlgLinDriveService.ListLinLdfModel != null) { foreach (var sig in ZlgLinDriveService.ListLinLdfModel) { candidates.Add(new DialogZlgCanLinRwConfigViewModel.SignalCandidate { MsgName = sig.MsgName, SignalName = sig.SignalName, Name = sig.Name, Desc = sig.SignalDesc, }); } } var pars = new DialogParameters { { "Title", "读写设置" }, { "CanLinConfigProId", SelectCanLinConfigPro.Id }, { "IsEditable", IsRwEditable }, { "WriteConfigs", writeClones }, { "ReadConfigs", readClones }, { "SignalCandidates", candidates }, }; DialogService.ShowDialog(nameof(DialogZlgCanLinRwConfigView), pars, r => { if (r.Result == ButtonResult.OK) { ReloadCurrentConfigPro(); } }); } catch (Exception ex) { MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } private void ReloadCurrentConfigPro() { var id = SelectCanLinConfigPro?.Id; InitLoadLinConfigPro(); if (id != null) { SelectCanLinConfigPro = linConfigPros.Find(a => a.Id == id.Value); SyncSelectedConfig(); } } private static CanLinRWConfigDto CloneRwDto(CanLinRWConfigDto src) { return new CanLinRWConfigDto { Id = src.Id, RWInfo = src.RWInfo, Name = src.Name, MsgFrameName = src.MsgFrameName, SignalName = src.SignalName, DefautValue = src.DefautValue, LogicRuleId = src.LogicRuleId, LogicRuleDto = src.LogicRuleDto, }; } private DelegateCommand? _SchEnableCmd; /// /// 调度表使能写入驱动。 /// public DelegateCommand SchEnableCmd { get { if (_SchEnableCmd == null) { _SchEnableCmd = new DelegateCommand(SchEnableCmdCall); } return _SchEnableCmd; } } private void SchEnableCmdCall(object par) { ZlgLinDriveService.SchEnable = CurrentSchEnable; } } }