周立功换同星
This commit is contained in:
@@ -12,7 +12,7 @@ namespace CANModule
|
||||
{
|
||||
containerRegistry.RegisterDialog<SelectCanMessageView>("SelectCanMessageView");
|
||||
containerRegistry.RegisterDialog<CollectCANSignalSettingView>("CollectCANSignalSettingView");
|
||||
containerRegistry.RegisterForNavigation<ZLGCANFDView>("ZLGCANFDView");
|
||||
containerRegistry.RegisterForNavigation<CANView>("CANView");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWPF>true</UseWPF>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWPF>true</UseWPF>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\UIShare\UIShare.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\TSMasterCAN\TSMasterCAN.csproj" />
|
||||
<ProjectReference Include="..\UIShare\UIShare.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Interop.TSMasterAPI">
|
||||
<HintPath>..\TSMasterCAN\Interop.TSMasterAPI.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
581
CANModule/ViewModels/CANViewModel.cs
Normal file
581
CANModule/ViewModels/CANViewModel.cs
Normal file
@@ -0,0 +1,581 @@
|
||||
|
||||
using Microsoft.Win32;
|
||||
using Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Threading;
|
||||
using TSMasterCAN;
|
||||
using UIShare.GlobalVariable;
|
||||
using UIShare.UIViewModel;
|
||||
|
||||
namespace CANModule.ViewModels
|
||||
{
|
||||
public class CANViewModel : BindableBase, IDialogAware
|
||||
{
|
||||
|
||||
#region 属性
|
||||
private string _Title = "同星CAN";
|
||||
|
||||
public string Title
|
||||
{
|
||||
get { return _Title; }
|
||||
set { SetProperty(ref _Title, value); }
|
||||
}
|
||||
private ObservableCollection<CanMessageShowVM> _CanMessageList = new();
|
||||
|
||||
public ObservableCollection<CanMessageShowVM> CanMessageList
|
||||
{
|
||||
get { return _CanMessageList; }
|
||||
set { SetProperty(ref _CanMessageList, value); }
|
||||
}
|
||||
private string _DBCChannel = "0";
|
||||
|
||||
public string DBCChannel
|
||||
{
|
||||
get { return _DBCChannel; }
|
||||
set { SetProperty(ref _DBCChannel, value); }
|
||||
}
|
||||
private bool _IsDirectlySend = false;
|
||||
|
||||
public bool IsDirectlySend
|
||||
{
|
||||
get { return _IsDirectlySend; }
|
||||
set { SetProperty(ref _IsDirectlySend, value); }
|
||||
}
|
||||
private ObservableCollection<string> _Message;
|
||||
public ObservableCollection<string> Message
|
||||
{
|
||||
get { return _Message; }
|
||||
set { SetProperty(ref _Message, value); }
|
||||
}
|
||||
private ObservableCollection<string> _Signal;
|
||||
public ObservableCollection<string> Signal
|
||||
{
|
||||
get { return _Signal; }
|
||||
set { SetProperty(ref _Signal, value); }
|
||||
}
|
||||
byte channel;
|
||||
private string _selectedMessage;
|
||||
public string SelectedMessage
|
||||
{
|
||||
get { return _selectedMessage; }
|
||||
set
|
||||
{
|
||||
if (_selectedMessage != value)
|
||||
{
|
||||
Signal = new(DBCParse.MsgDatabase[channel].Where(x => $"[0x{x.msg_id:X}]{x.msg_name}" == value).First().signal_Name);
|
||||
_selectedMessage = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _selectedSignal;
|
||||
public string SelectedSignal
|
||||
{
|
||||
get { return _selectedSignal; }
|
||||
set { SetProperty(ref _selectedSignal, value); }
|
||||
}
|
||||
|
||||
private string _signalValue;
|
||||
public string SignalValue
|
||||
{
|
||||
get { return _signalValue; }
|
||||
set { SetProperty(ref _signalValue, value); }
|
||||
}
|
||||
|
||||
private string _cycleSendInterval;
|
||||
public string CycleSendInterval
|
||||
{
|
||||
get { return _cycleSendInterval; }
|
||||
set { SetProperty(ref _cycleSendInterval, value); }
|
||||
}
|
||||
|
||||
private string _messageSendChannel = "0";
|
||||
public string MessageSendChannel
|
||||
{
|
||||
get { return _messageSendChannel; }
|
||||
set { SetProperty(ref _messageSendChannel, value); }
|
||||
}
|
||||
public string BLFPath
|
||||
{
|
||||
get => _systemConfig?.DefaultBLFFilePath ?? "";
|
||||
set
|
||||
{
|
||||
if (_systemConfig != null && _systemConfig.DefaultBLFFilePath != value)
|
||||
{
|
||||
_systemConfig.DefaultBLFFilePath = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string DBCPath
|
||||
{
|
||||
get => _systemConfig?.DefaultDBCFilePath ?? "";
|
||||
set
|
||||
{
|
||||
if (_systemConfig != null && _systemConfig.DefaultDBCFilePath != value)
|
||||
{
|
||||
_systemConfig.DefaultDBCFilePath = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
private bool _IsSaved;
|
||||
public bool IsSaved
|
||||
{
|
||||
get { return _IsSaved; }
|
||||
set { SetProperty(ref _IsSaved, value); }
|
||||
}
|
||||
public ObservableCollection<AutoDBCLoadItem> DBCAutoLoadList
|
||||
{
|
||||
get => _systemConfig?.DBCAutoLoadList ?? new ObservableCollection<AutoDBCLoadItem>();
|
||||
}
|
||||
|
||||
private AutoDBCLoadItem _SelectedDcAutoLoad;
|
||||
public AutoDBCLoadItem SelectedDcAutoLoad
|
||||
{
|
||||
get { return _SelectedDcAutoLoad; }
|
||||
set { SetProperty(ref _SelectedDcAutoLoad, value); }
|
||||
}
|
||||
private TSMaster.APP_CHANNEL[] _appChannelNames = new[] { TSMaster.APP_CHANNEL.CHN1, TSMaster.APP_CHANNEL.CHN2, TSMaster.APP_CHANNEL.CHN3, TSMaster.APP_CHANNEL.CHN4 };
|
||||
public TSMaster.APP_CHANNEL[] APP_CHANNEL
|
||||
{
|
||||
get { return _appChannelNames; }
|
||||
set { SetProperty(ref _appChannelNames, value); }
|
||||
}
|
||||
|
||||
private TSMaster.APP_CHANNEL _aIdxChn;
|
||||
public TSMaster.APP_CHANNEL AIdxChn
|
||||
{
|
||||
get { return _aIdxChn; }
|
||||
set { SetProperty(ref _aIdxChn, value); }
|
||||
}
|
||||
|
||||
private int _aID;
|
||||
public int AID
|
||||
{
|
||||
get { return _aID; }
|
||||
set { SetProperty(ref _aID, value); }
|
||||
}
|
||||
|
||||
private bool _aIsTx;
|
||||
public bool AIsTx
|
||||
{
|
||||
get { return _aIsTx; }
|
||||
set { SetProperty(ref _aIsTx, value); }
|
||||
}
|
||||
|
||||
private bool _aIsExt;
|
||||
public bool AIsExt
|
||||
{
|
||||
get { return _aIsExt; }
|
||||
set { SetProperty(ref _aIsExt, value); }
|
||||
}
|
||||
|
||||
private bool _aIsRemote;
|
||||
public bool AIsRemote
|
||||
{
|
||||
get { return _aIsRemote; }
|
||||
set { SetProperty(ref _aIsRemote, value); }
|
||||
}
|
||||
|
||||
private byte _aDlc;
|
||||
public byte ADLC
|
||||
{
|
||||
get { return _aDlc; }
|
||||
set { SetProperty(ref _aDlc, value); }
|
||||
}
|
||||
|
||||
private byte[] _aDataArray;
|
||||
public byte[] ADataArray
|
||||
{
|
||||
get { return _aDataArray; }
|
||||
set { SetProperty(ref _aDataArray, value); }
|
||||
}
|
||||
|
||||
private bool _aIsFD = true;
|
||||
public bool AIsFD
|
||||
{
|
||||
get { return _aIsFD; }
|
||||
set { SetProperty(ref _aIsFD, value); }
|
||||
}
|
||||
|
||||
private bool _aIsBRS = false;
|
||||
public bool AIsBRS
|
||||
{
|
||||
get { return _aIsBRS; }
|
||||
set { SetProperty(ref _aIsBRS, value); }
|
||||
}
|
||||
|
||||
private bool _AutoSetting = true;
|
||||
public bool AutoSetting
|
||||
{
|
||||
get { return _AutoSetting; }
|
||||
set { SetProperty(ref _AutoSetting, value); }
|
||||
}
|
||||
|
||||
private string _CustomMessage = "[00,11,22,33,AA,BB,CC,DD]";
|
||||
public string CustomMessage
|
||||
{
|
||||
get { return _CustomMessage; }
|
||||
set { SetProperty(ref _CustomMessage, value); }
|
||||
}
|
||||
|
||||
private float _CustomSendCycleInterval = 0.0f;
|
||||
public float CustomSendCycleInterval
|
||||
{
|
||||
get { return _CustomSendCycleInterval; }
|
||||
set { SetProperty(ref _CustomSendCycleInterval, value); }
|
||||
}
|
||||
private bool _UpdateToDB;
|
||||
public bool UpdateToDB
|
||||
{
|
||||
get { return _UpdateToDB; }
|
||||
set { SetProperty(ref _UpdateToDB, value); }
|
||||
}
|
||||
#endregion
|
||||
#region 命令
|
||||
public ICommand SelectBLFPathCommand { get; set; }
|
||||
public ICommand SaveBLFPathCommand { get; set; }
|
||||
public ICommand StartTranscirbeCommand { get; set; }
|
||||
public ICommand EndTranscirbeCommand { get; set; }
|
||||
public ICommand CloseCommand { get; set; }
|
||||
public ICommand ConnectCanCommand { get; set; }
|
||||
public ICommand CloseCanCommand { get; set; }
|
||||
public ICommand ClearCycleCommand { get; set; }
|
||||
public ICommand UpLoadDBCCommand { get; set; }
|
||||
public ICommand ChangeDBCCommand { get; set; }
|
||||
public ICommand LoadDBCCommand { get; set; }
|
||||
public ICommand CheckDBCCommand { get; set; }
|
||||
public ICommand InitTSMasterCommand { get; set; }
|
||||
public ICommand ReleaseTSMasterCommand { get; set; }
|
||||
public ICommand LoadMessageCommand { get; set; }
|
||||
public ICommand SetAndSendMessageCommand { get; set; }
|
||||
public ICommand DeleteDcAutoLoadCommand { get; set; }
|
||||
public ICommand SendCustomMessageCommand { get; set; }
|
||||
|
||||
#endregion
|
||||
private IEventAggregator _eventAggregator { get; set; }
|
||||
private CAN? _canfd;
|
||||
private SystemConfig? _systemConfig;
|
||||
private readonly DeviceManager _deviceManager;
|
||||
private IDialogService _dialogService { get; set; }
|
||||
CancellationTokenSource cts = new CancellationTokenSource();
|
||||
public CANViewModel(IContainerProvider containerProvider)
|
||||
{
|
||||
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||
_systemConfig = containerProvider.Resolve<SystemConfig>();
|
||||
_deviceManager = containerProvider.Resolve<DeviceManager>();
|
||||
_canfd = _deviceManager.CANFD;
|
||||
_dialogService = containerProvider.Resolve<IDialogService>();
|
||||
SelectBLFPathCommand = new DelegateCommand(SelectBLFPath);
|
||||
SaveBLFPathCommand = new DelegateCommand(SaveBLFPath);
|
||||
StartTranscirbeCommand = new DelegateCommand(StartTranscirbe);
|
||||
EndTranscirbeCommand = new DelegateCommand(EndTranscirbe);
|
||||
CloseCommand = new DelegateCommand(Close);
|
||||
ConnectCanCommand = new DelegateCommand(ConnectCan);
|
||||
CloseCanCommand = new DelegateCommand(CloseCan);
|
||||
ClearCycleCommand = new DelegateCommand(ClearCycle);
|
||||
UpLoadDBCCommand = new DelegateCommand(UpLoadDBC);
|
||||
ChangeDBCCommand = new DelegateCommand(ChangeDBC);
|
||||
LoadDBCCommand = new DelegateCommand(LoadDBC);
|
||||
CheckDBCCommand = new DelegateCommand(CheckDBC);
|
||||
InitTSMasterCommand = new DelegateCommand(InitTSMaster);
|
||||
ReleaseTSMasterCommand = new DelegateCommand(ReleaseTSMaster);
|
||||
SetAndSendMessageCommand = new DelegateCommand(SetAndSendMessage);
|
||||
LoadMessageCommand = new DelegateCommand(LoadMessage);
|
||||
DeleteDcAutoLoadCommand = new DelegateCommand(DeleteDcAutoLoad);
|
||||
SendCustomMessageCommand = new DelegateCommand(SendCustomMessage);
|
||||
}
|
||||
|
||||
#region 命令
|
||||
private void SendCustomMessage()
|
||||
{
|
||||
try
|
||||
{
|
||||
ADataArray = 报文转换(CustomMessage);
|
||||
if (ADataArray.Length > byte.MaxValue) throw new Exception("报文数量超过上限!");
|
||||
if (AutoSetting)
|
||||
{
|
||||
ADLC = (byte)ADataArray.Length;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_dialogService.ShowDialog("MessageDialog", new DialogParameters
|
||||
{
|
||||
{ "message", $"报文转换失败:{ex.Message}" }
|
||||
});
|
||||
return;
|
||||
}
|
||||
var re = CAN.SendMsg(AIdxChn, AID, AIsTx, AIsExt,
|
||||
AIsRemote, ADLC, ADataArray, AIsFD, AIsBRS, UpdateToDB, CustomSendCycleInterval);
|
||||
}
|
||||
private void DeleteDcAutoLoad()
|
||||
{
|
||||
DBCAutoLoadList.Remove(SelectedDcAutoLoad);
|
||||
ConfigService.Save(_systemConfig);
|
||||
}
|
||||
private void LoadMessage()
|
||||
{
|
||||
if (int.TryParse(MessageSendChannel, out int channel))
|
||||
{
|
||||
Message = new(DBCParse.MsgDatabase[channel].Select(s => $"[0x{s.msg_id:X}]{s.msg_name}"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void SetAndSendMessage()
|
||||
{
|
||||
if (int.TryParse(CycleSendInterval, out int sendPeriod) && double.TryParse(SignalValue, out double SValue) && byte.TryParse(MessageSendChannel, out byte c))
|
||||
{
|
||||
channel = c;
|
||||
var message = SelectedMessage.Split(']')[1];
|
||||
var re = CAN.SetSignalValue(channel, message, SelectedSignal, SValue, IsDirectlySend, sendPeriod);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void ReleaseTSMaster()
|
||||
{
|
||||
CAN.Release();
|
||||
}
|
||||
|
||||
private void InitTSMaster()
|
||||
{
|
||||
var re = CAN.Init("ACP");
|
||||
}
|
||||
private void UpLoadDBC()
|
||||
{
|
||||
var re = CAN.UnLoadDBC();
|
||||
}
|
||||
|
||||
private void ChangeDBC()
|
||||
{
|
||||
var dialog = new OpenFileDialog
|
||||
{
|
||||
Title = "更换DBC文件",
|
||||
Filter = "DBC 文件 (*.dbc)|*.dbc|所有文件 (*.*)|*.*",
|
||||
DefaultExt = ".dbc",
|
||||
};
|
||||
if (dialog.ShowDialog() == true)
|
||||
{
|
||||
DBCPath = Path.GetFullPath(dialog.FileName);
|
||||
ConfigService.Save(_systemConfig);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadDBC()
|
||||
{
|
||||
if (int.TryParse(DBCChannel, out var channel))
|
||||
{
|
||||
var re = CAN.LoadDBC(DBCPath, [channel], out _);
|
||||
if (re == 0 && IsSaved)
|
||||
{
|
||||
var item = DBCAutoLoadList.Where(s => s.DBCChannel == channel).FirstOrDefault();
|
||||
if (item == null)
|
||||
{
|
||||
DBCAutoLoadList.Add(new AutoDBCLoadItem
|
||||
{
|
||||
DBCFilePath = DBCPath,
|
||||
DBCChannel = channel
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
DBCAutoLoadList.Remove(item);
|
||||
DBCAutoLoadList.Add(new AutoDBCLoadItem
|
||||
{
|
||||
DBCFilePath = DBCPath,
|
||||
DBCChannel = channel
|
||||
});
|
||||
}
|
||||
ConfigService.Save(_systemConfig);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckDBC()
|
||||
{
|
||||
if (int.TryParse(DBCChannel, out var channel))
|
||||
{
|
||||
_dialogService.ShowDialog("DBCInfo", new DialogParameters
|
||||
{
|
||||
{ "can_Network", DBCParse.can_Network },
|
||||
{ "MsgDatabase", DBCParse.MsgDatabase[channel] }
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
private void ClearCycle()
|
||||
{
|
||||
var re = CAN.DeleteCyclicMsgs();
|
||||
}
|
||||
|
||||
private void CloseCan()
|
||||
{
|
||||
var re = CAN.DisConnect();
|
||||
}
|
||||
|
||||
private void ConnectCan()
|
||||
{
|
||||
var re = CAN.Connect();
|
||||
}
|
||||
private void EndTranscirbe()
|
||||
{
|
||||
var re = CAN.StopLogging();
|
||||
}
|
||||
|
||||
private void StartTranscirbe()
|
||||
{
|
||||
var re = CAN.StartLogging(BLFPath);
|
||||
}
|
||||
|
||||
private void SaveBLFPath()
|
||||
{
|
||||
_systemConfig.DefaultBLFFilePath = BLFPath;
|
||||
ConfigService.Save(_systemConfig);
|
||||
}
|
||||
|
||||
private void SelectBLFPath()
|
||||
{
|
||||
var dialog = new SaveFileDialog
|
||||
{
|
||||
Title = "保存 CAN报文回放 BLF 文件",
|
||||
Filter = "BLF 文件 (*.blf)|*.blf|所有文件 (*.*)|*.*",
|
||||
DefaultExt = ".blf",
|
||||
FileName = "log.blf",
|
||||
OverwritePrompt = true
|
||||
};
|
||||
if (dialog.ShowDialog() == true)
|
||||
{
|
||||
BLFPath = Path.GetFullPath(dialog.FileName);
|
||||
}
|
||||
}
|
||||
private void Close()
|
||||
{
|
||||
RequestClose.Invoke();
|
||||
}
|
||||
#endregion
|
||||
public byte[] 报文转换(string s)
|
||||
{
|
||||
s = s.Replace("[", string.Empty).Replace("]", string.Empty);
|
||||
var strs = s.Split(',', StringSplitOptions.RemoveEmptyEntries);
|
||||
byte[] bytes = new byte[strs.Length];
|
||||
for (int i = 0; i < strs.Length; i++)
|
||||
{
|
||||
bytes[i] = Convert.ToByte(strs[i], 16);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private async Task Refresh(CancellationToken ct = default)
|
||||
{
|
||||
while (ct.IsCancellationRequested == false)
|
||||
{
|
||||
var temp = CAN.RealTimeMessages.Select(s => s.Value).ToArray();
|
||||
foreach (var item in temp)
|
||||
{
|
||||
var find = CanMessageList.FirstOrDefault(s => s.报文ID == item.FIdentifier);
|
||||
if (find != null)
|
||||
{
|
||||
if (find.通道 != item.FIdxChn) find.通道 = item.FIdxChn;
|
||||
if (find.报文ID != item.FIdentifier) find.报文ID = item.FIdentifier;
|
||||
if (find.时间戳 != item.FTimeUS) find.时间戳 = item.FTimeUS;
|
||||
if (find.FD != item.FIsFD) find.FD = item.FIsFD;
|
||||
if (find.IsTx != item.FIsTx) find.IsTx = item.FIsTx;
|
||||
|
||||
var 长度改变 = find.长度 == item.FDLC;
|
||||
var 数据改变 = find.Bytes.SequenceEqual(item.FData);
|
||||
if (长度改变 || 数据改变)
|
||||
{
|
||||
find.长度 = item.FDLC;
|
||||
Array.Copy(item.FData, 0, find.Bytes, 0, 64);
|
||||
find.报文 = 十六进制字符串转换(item.FData.AsSpan(0, find.长度));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var 报文temp = new CanMessageShowVM()
|
||||
{
|
||||
通道 = item.FIdxChn,
|
||||
报文ID = item.FIdentifier,
|
||||
时间戳 = item.FTimeUS,
|
||||
FD = item.FIsFD,
|
||||
IsTx = item.FIsTx,
|
||||
长度 = item.FDLC,
|
||||
报文 = 十六进制字符串转换(item.FData.AsSpan(0, item.FDLC)),
|
||||
};
|
||||
Array.Copy(item.FData, 0, 报文temp.Bytes, 0, 64);
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
CanMessageList.Add(报文temp);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
await Task.Delay(50, ct);
|
||||
}
|
||||
}
|
||||
string 十六进制字符串转换(Span<byte> s)
|
||||
{
|
||||
if (s == null || s.Length == 0)
|
||||
return "[]";
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.Append('[');
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
{
|
||||
sb.Append("0x");
|
||||
sb.Append(s[i].ToString("X2"));
|
||||
if (i < s.Length - 1)
|
||||
sb.Append(", ");
|
||||
}
|
||||
sb.Append(']');
|
||||
return sb.ToString();
|
||||
}
|
||||
#region dialog规范
|
||||
public DialogCloseListener RequestClose { get; set; }
|
||||
|
||||
public bool CanCloseDialog()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnDialogClosed()
|
||||
{
|
||||
cts.Cancel();
|
||||
}
|
||||
|
||||
public void OnDialogOpened(IDialogParameters parameters)
|
||||
{
|
||||
Task.Run(() => Refresh(cts.Token), cts.Token);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Model;
|
||||
using TSMasterCAN;
|
||||
using UIShare.GlobalVariable;
|
||||
using UIShare.PubEvent;
|
||||
using UIShare.UIViewModel;
|
||||
using UIShare.ViewModelBase;
|
||||
using ZLGUSBCANFD;
|
||||
|
||||
namespace CANModule.ViewModels
|
||||
{
|
||||
public class CollectCANSignalSettingViewModel : DialogViewModelBase
|
||||
public class CollectCANSignalSettingViewModel : BindableBase, IDialogAware
|
||||
{
|
||||
#region 字段
|
||||
private ZLGCANFD? _canfd;
|
||||
private SystemConfig? _systemConfig;
|
||||
#endregion
|
||||
|
||||
#region 属性
|
||||
public ObservableCollection<CANSignalConfig> ConfigurationList
|
||||
{
|
||||
get => _systemConfig?.ConfigurationList ?? new ObservableCollection<CANSignalConfig>();
|
||||
get => _systemConfig.ConfigurationList;
|
||||
set
|
||||
{
|
||||
if(_systemConfig.ConfigurationList != value)
|
||||
{
|
||||
_systemConfig.ConfigurationList = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private ObservableCollection<int> _ChannelList;
|
||||
public ObservableCollection<int> ChannelList
|
||||
{
|
||||
get => _ChannelList;
|
||||
set => SetProperty(ref _ChannelList, value);
|
||||
}
|
||||
private ObservableCollection<string> _messageList;
|
||||
public ObservableCollection<string> MessageList
|
||||
{
|
||||
@@ -39,42 +50,23 @@ namespace CANModule.ViewModels
|
||||
set => SetProperty(ref _signalList, value);
|
||||
}
|
||||
|
||||
private string _title = "信号采集设置";
|
||||
private string _title= "信号采集设置";
|
||||
public string Title
|
||||
{
|
||||
get => _title;
|
||||
set => SetProperty(ref _title, value);
|
||||
}
|
||||
|
||||
private string _selectedMessage;
|
||||
public string SelectedMessage
|
||||
{
|
||||
get => _selectedMessage;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _selectedMessage, value))
|
||||
if (SetProperty(ref _selectedMessage,value))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value) && _canfd != null)
|
||||
if (value != null && value != "")
|
||||
{
|
||||
var db = _canfd.DBCParser.MsgDatabase;
|
||||
if (MessageChannel >= 0 && MessageChannel < db.Count)
|
||||
{
|
||||
var targetMsg = db[MessageChannel]
|
||||
.FirstOrDefault(x => $"[0x{x.msg_id:X}]{x.msg_name}" == value);
|
||||
|
||||
if (targetMsg != null && targetMsg.signal_Name != null)
|
||||
{
|
||||
SignalList = new ObservableCollection<string>(targetMsg.signal_Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
SignalList = new ObservableCollection<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SignalList = new ObservableCollection<string>();
|
||||
SignalList = new(DBCParse.MsgDatabase[MessageChannel].Where(x => $"[0x{x.msg_id:X}]{x.msg_name}" == value).First().signal_Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,7 +78,6 @@ namespace CANModule.ViewModels
|
||||
get => _SelectedItem;
|
||||
set => SetProperty(ref _SelectedItem, value);
|
||||
}
|
||||
|
||||
private string _selectedSignal;
|
||||
public string SelectedSignal
|
||||
{
|
||||
@@ -94,7 +85,7 @@ namespace CANModule.ViewModels
|
||||
set => SetProperty(ref _selectedSignal, value);
|
||||
}
|
||||
|
||||
private int _MessageChannel=-1;
|
||||
private int _MessageChannel;
|
||||
public int MessageChannel
|
||||
{
|
||||
get => _MessageChannel;
|
||||
@@ -103,127 +94,91 @@ namespace CANModule.ViewModels
|
||||
if (_MessageChannel != value)
|
||||
{
|
||||
_MessageChannel = value;
|
||||
|
||||
MessageList = new(DBCParse.MsgDatabase[value].Select(s => $"[0x{s.msg_id:X}]{s.msg_name}"));
|
||||
SignalList = new();
|
||||
SelectedMessage = null;
|
||||
SelectedSignal = null;
|
||||
SignalList = new ObservableCollection<string>();
|
||||
|
||||
if (_canfd != null)
|
||||
{
|
||||
var db = _canfd.DBCParser.MsgDatabase;
|
||||
if (db != null && value >= 0 && value < db.Count)
|
||||
{
|
||||
MessageList = new ObservableCollection<string>(
|
||||
db[value].Select(s => $"[0x{s.msg_id:X}]{s.msg_name}")
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageList = new ObservableCollection<string>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageList = new ObservableCollection<string>();
|
||||
}
|
||||
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int _collectionInterval = 1000;
|
||||
private int _collectionInterval=1000;
|
||||
public int CollectionInterval
|
||||
{
|
||||
get => _collectionInterval;
|
||||
set => SetProperty(ref _collectionInterval, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 命令
|
||||
#endregion Properties
|
||||
public ICommand AddCommand { get; set; }
|
||||
public ICommand CloseCommand { get; set; }
|
||||
public ICommand SaveCommand { get; set; }
|
||||
public ICommand DeleteCommand { get; set; }
|
||||
#endregion
|
||||
|
||||
public CollectCANSignalSettingViewModel(IContainerProvider containerProvider) : base(containerProvider)
|
||||
public ICommand CloseCommand { get; set; }
|
||||
public ICommand LoadCommand { get; set; }
|
||||
public ICommand SaveCommand { get; set; }
|
||||
public ICommand DeleteCommand { get; set; }
|
||||
public DialogCloseListener RequestClose { get; set; }
|
||||
public IEventAggregator _eventAggregator { get; set; }
|
||||
private SystemConfig _systemConfig;
|
||||
public CollectCANSignalSettingViewModel(IContainerProvider containerProvider)
|
||||
{
|
||||
_eventAggregator=containerProvider.Resolve<IEventAggregator>();
|
||||
_systemConfig= containerProvider.Resolve<SystemConfig>();
|
||||
CloseCommand = new DelegateCommand(Close);
|
||||
AddCommand = new DelegateCommand(Add);
|
||||
LoadCommand = new DelegateCommand(Load);
|
||||
SaveCommand = new DelegateCommand(Save);
|
||||
DeleteCommand = new DelegateCommand(Delete);
|
||||
}
|
||||
|
||||
#region Dialog 生命周期
|
||||
public override void OnDialogOpened(IDialogParameters parameters)
|
||||
{
|
||||
_systemConfig = parameters.GetValue<SystemConfig>("SystemConfig");
|
||||
_canfd = _systemConfig?.CANFD;
|
||||
string title = _systemConfig.Title;
|
||||
char lastChar = title[title.Length - 1];
|
||||
// 3. "TestCellX"转int
|
||||
MessageChannel = int.Parse(lastChar.ToString())-1;
|
||||
if (MessageChannel >= 4) MessageChannel -= 4;
|
||||
RaisePropertyChanged(nameof(ConfigurationList));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 命令处理
|
||||
private void Delete()
|
||||
{
|
||||
if (SelectedItem != null)
|
||||
{
|
||||
_systemConfig?.ConfigurationList.Remove(SelectedItem);
|
||||
}
|
||||
ConfigurationList.Remove(SelectedItem);
|
||||
}
|
||||
|
||||
private void Save()
|
||||
{
|
||||
_eventAggregator.GetEvent<CollectedCANMessageChangedEvent>().Publish();
|
||||
ConfigService.Save(_systemConfig);
|
||||
}
|
||||
|
||||
private void Load()
|
||||
{
|
||||
ChannelList = new ObservableCollection<int>(Enumerable.Range(0, 12));
|
||||
}
|
||||
|
||||
|
||||
private void Add()
|
||||
{
|
||||
if (string.IsNullOrEmpty(SelectedSignal) || string.IsNullOrEmpty(SelectedMessage) || CollectionInterval < 100)
|
||||
if (string.IsNullOrEmpty(SelectedSignal) || string.IsNullOrEmpty(SelectedMessage)||CollectionInterval<100)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_systemConfig == null) return;
|
||||
|
||||
string hexString = ExtractHex(SelectedMessage);
|
||||
if (string.IsNullOrEmpty(hexString)) return;
|
||||
|
||||
int decimalValue = ConvertHexToDecimal(hexString);
|
||||
if (_systemConfig.ConfigurationList.Any(x => x.SignalName == SelectedSignal && x.Channel == MessageChannel))
|
||||
if (string.IsNullOrEmpty(hexString))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_systemConfig.ConfigurationList.Add(new CANSignalConfig
|
||||
int decimalValue = ConvertHexToDecimal(hexString);
|
||||
if (ConfigurationList.Where(x => x.SignalName == SelectedSignal&&x.Channel==MessageChannel).FirstOrDefault() != null) return;
|
||||
ConfigurationList.Add(new CANSignalConfig
|
||||
{
|
||||
CollectionID = Guid.NewGuid(),
|
||||
Channel = MessageChannel,
|
||||
MethodName = CANSignalBroadcaster.BuildMethodName((uint)decimalValue, SelectedSignal),
|
||||
Channel = MessageChannel,
|
||||
MessageName = ExtractMessageName(SelectedMessage),
|
||||
SignalName = SelectedSignal,
|
||||
MessageID = decimalValue,
|
||||
CollectionInterval = CollectionInterval
|
||||
});
|
||||
}
|
||||
|
||||
private string ExtractHex(string input)
|
||||
{
|
||||
int startIndex = input.IndexOf("0x") + 2;
|
||||
int endIndex = input.IndexOf("]", startIndex);
|
||||
int endIndex = input.IndexOf("]", startIndex);
|
||||
if (startIndex >= 2 && endIndex > startIndex)
|
||||
{
|
||||
return input.Substring(startIndex, endIndex - startIndex);
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private int ConvertHexToDecimal(string hex)
|
||||
{
|
||||
try
|
||||
@@ -232,20 +187,37 @@ namespace CANModule.ViewModels
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private string ExtractMessageName(string input)
|
||||
{
|
||||
var parts = input.Split(']');
|
||||
return parts.Length > 1 ? parts[1] : string.Empty;
|
||||
return parts.Length > 1 ? parts[1] : string.Empty;
|
||||
}
|
||||
|
||||
private void Close()
|
||||
{
|
||||
RequestClose.Invoke();
|
||||
}
|
||||
#endregion
|
||||
|
||||
public bool CanCloseDialog()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnDialogClosed()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnDialogOpened(IDialogParameters parameters)
|
||||
{
|
||||
if (DBCParse.MsgDatabase.Count == 0 || DBCParse.MsgDatabase[0].Count==0)
|
||||
{
|
||||
|
||||
}
|
||||
MessageList = new(DBCParse.MsgDatabase[0].Select(s => $"[0x{s.msg_id:X}]{s.msg_name}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using UIShare.ViewModelBase;
|
||||
using ZLGUSBCANFD;
|
||||
using TSMasterCAN;
|
||||
using UIShare.UIViewModel;
|
||||
|
||||
namespace CANModule.ViewModels
|
||||
{
|
||||
public class SelectCanMessageViewModel : DialogViewModelBase
|
||||
public class SelectCanMessageViewModel : BindableBase, IDialogAware
|
||||
{
|
||||
#region 字段
|
||||
private ZLGCANFD? _canfd;
|
||||
#endregion
|
||||
|
||||
#region 属性
|
||||
public DialogCloseListener RequestClose { get; set; }
|
||||
|
||||
private ObservableCollection<int> _ChannelList;
|
||||
public ObservableCollection<int> ChannelList
|
||||
{
|
||||
get => _ChannelList;
|
||||
set => SetProperty(ref _ChannelList, value);
|
||||
}
|
||||
|
||||
private ObservableCollection<string> _messageList;
|
||||
public ObservableCollection<string> MessageList
|
||||
{
|
||||
@@ -44,7 +41,6 @@ namespace CANModule.ViewModels
|
||||
get => _title;
|
||||
set => SetProperty(ref _title, value);
|
||||
}
|
||||
|
||||
private string _selectedMessage;
|
||||
public string SelectedMessage
|
||||
{
|
||||
@@ -53,27 +49,9 @@ namespace CANModule.ViewModels
|
||||
{
|
||||
if (SetProperty(ref _selectedMessage, value))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value) && _canfd != null)
|
||||
if (value != null && value != "")
|
||||
{
|
||||
var db = _canfd.DBCParser.MsgDatabase;
|
||||
if (MessageChannel >= 0 && MessageChannel < db.Count)
|
||||
{
|
||||
var targetMsg = db[MessageChannel]
|
||||
.FirstOrDefault(x => $"[0x{x.msg_id:X}]{x.msg_name}" == value);
|
||||
|
||||
if (targetMsg != null && targetMsg.signal_Name != null)
|
||||
{
|
||||
SignalList = new ObservableCollection<string>(targetMsg.signal_Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
SignalList = new ObservableCollection<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SignalList = new ObservableCollection<string>();
|
||||
SignalList = new(DBCParse.MsgDatabase[MessageChannel].Where(x => $"[0x{x.msg_id:X}]{x.msg_name}" == value).First().signal_Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -85,8 +63,7 @@ namespace CANModule.ViewModels
|
||||
get => _selectedSignal;
|
||||
set => SetProperty(ref _selectedSignal, value);
|
||||
}
|
||||
|
||||
private int _MessageChannel = -1;
|
||||
private int _MessageChannel;
|
||||
public int MessageChannel
|
||||
{
|
||||
get => _MessageChannel;
|
||||
@@ -94,94 +71,84 @@ namespace CANModule.ViewModels
|
||||
{
|
||||
if (_MessageChannel != value)
|
||||
{
|
||||
_MessageChannel = value;
|
||||
|
||||
// 1. 先安全清空旧的选择项和信号列表
|
||||
_MessageChannel=value;
|
||||
MessageList = new(DBCParse.MsgDatabase[value].Select(s => $"[0x{s.msg_id:X}]{s.msg_name}"));
|
||||
SignalList = new();
|
||||
SelectedMessage = null;
|
||||
SelectedSignal = null;
|
||||
SignalList = new ObservableCollection<string>();
|
||||
|
||||
// 2. 刷新当前通道的报文列表
|
||||
if (_canfd != null)
|
||||
{
|
||||
var db = _canfd.DBCParser.MsgDatabase;
|
||||
if (db != null && value >= 0 && value < db.Count)
|
||||
{
|
||||
MessageList = new ObservableCollection<string>(
|
||||
db[value].Select(s => $"[0x{s.msg_id:X}]{s.msg_name}")
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageList = new ObservableCollection<string>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageList = new ObservableCollection<string>();
|
||||
}
|
||||
|
||||
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)
|
||||
public DialogCloseListener RequestClose { get; set; }
|
||||
public SelectCanMessageViewModel()
|
||||
{
|
||||
CloseCommand = new DelegateCommand(Close);
|
||||
GetSelectedMessageCommand = new DelegateCommand(GetSelectedMessage);
|
||||
GetSelectedSignalCommand = new DelegateCommand(GetSelectedSignal);
|
||||
LoadCommand = new DelegateCommand(Load);
|
||||
}
|
||||
|
||||
#region Dialog 生命周期
|
||||
public override void OnDialogOpened(IDialogParameters parameters)
|
||||
{
|
||||
_canfd = parameters.GetValue<ZLGCANFD>("CANFD");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 命令处理
|
||||
private void Close()
|
||||
{
|
||||
RequestClose.Invoke();
|
||||
}
|
||||
|
||||
private void Load()
|
||||
{
|
||||
int maxCh = _canfd?.DBCParser.MaxChannels ?? 4;
|
||||
ChannelList = new ObservableCollection<int>(Enumerable.Range(0, maxCh));
|
||||
ChannelList = new ObservableCollection<int>(Enumerable.Range(0, 12));
|
||||
}
|
||||
|
||||
private void GetSelectedSignal()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(SelectedSignal))
|
||||
if (SelectedSignal!=null)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
Clipboard.SetDataObject(SelectedSignal);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void GetSelectedMessage()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(SelectedMessage) && SelectedMessage.Contains(']'))
|
||||
if (SelectedSignal != null)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
Clipboard.SetDataObject(SelectedMessage);
|
||||
Clipboard.SetDataObject(SelectedMessage.Split("]")[1]);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void Close()
|
||||
{
|
||||
RequestClose.Invoke();
|
||||
}
|
||||
|
||||
public bool CanCloseDialog()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnDialogClosed()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnDialogOpened(IDialogParameters parameters)
|
||||
{
|
||||
MessageList = new(DBCParse.MsgDatabase[0].Select(s => $"[0x{s.msg_id:X}]{s.msg_name}"));
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,649 +0,0 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using UIShare.GlobalVariable;
|
||||
using UIShare.UIViewModel;
|
||||
using UIShare.ViewModelBase;
|
||||
using ZLGUSBCANFD;
|
||||
|
||||
namespace CANModule.ViewModels
|
||||
{
|
||||
public class ZLGCANFDViewModel : NavigateViewModelBase
|
||||
{
|
||||
#region 字段
|
||||
private ZLGCANFD? _canfd;
|
||||
private SystemConfig? _systemConfig;
|
||||
private CancellationTokenSource? _refreshCts;
|
||||
private readonly DeviceManager _deviceManager;
|
||||
#endregion
|
||||
|
||||
#region 属性
|
||||
private string _Title = "周立功CAN";
|
||||
public string Title
|
||||
{
|
||||
get => _Title;
|
||||
set => SetProperty(ref _Title, value);
|
||||
}
|
||||
|
||||
private ObservableCollection<CanMessageShowVM> _CanMessageList = new();
|
||||
public ObservableCollection<CanMessageShowVM> CanMessageList
|
||||
{
|
||||
get => _CanMessageList;
|
||||
set => SetProperty(ref _CanMessageList, value);
|
||||
}
|
||||
|
||||
private int _DBCChannel = 0;
|
||||
public int DBCChannel
|
||||
{
|
||||
get => _DBCChannel;
|
||||
set => SetProperty(ref _DBCChannel, value);
|
||||
}
|
||||
|
||||
private bool _IsDirectlySend = false;
|
||||
public bool IsDirectlySend
|
||||
{
|
||||
get => _IsDirectlySend;
|
||||
set => SetProperty(ref _IsDirectlySend, value);
|
||||
}
|
||||
|
||||
private ObservableCollection<string> _Message;
|
||||
public ObservableCollection<string> Message
|
||||
{
|
||||
get => _Message;
|
||||
set => SetProperty(ref _Message, value);
|
||||
}
|
||||
|
||||
private ObservableCollection<string> _Signal;
|
||||
public ObservableCollection<string> Signal
|
||||
{
|
||||
get => _Signal;
|
||||
set => SetProperty(ref _Signal, value);
|
||||
}
|
||||
|
||||
private byte _channel;
|
||||
private string _selectedMessage;
|
||||
public string SelectedMessage
|
||||
{
|
||||
get => _selectedMessage;
|
||||
set
|
||||
{
|
||||
if (_selectedMessage != value)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value) && _canfd != null)
|
||||
{
|
||||
var db = _canfd.DBCParser.MsgDatabase;
|
||||
if (_channel >= 0 && _channel < db.Count)
|
||||
{
|
||||
var targetMsg = db[(int)_channel]
|
||||
.FirstOrDefault(x => $"[0x{x.msg_id:X}]{x.msg_name}" == value);
|
||||
|
||||
if (targetMsg != null && targetMsg.signal_Name != null)
|
||||
{
|
||||
Signal = new ObservableCollection<string>(targetMsg.signal_Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
Signal = new ObservableCollection<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Signal = new ObservableCollection<string>();
|
||||
}
|
||||
_selectedMessage = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _selectedSignal;
|
||||
public string SelectedSignal
|
||||
{
|
||||
get => _selectedSignal;
|
||||
set => SetProperty(ref _selectedSignal, value);
|
||||
}
|
||||
|
||||
private string _signalValue;
|
||||
public string SignalValue
|
||||
{
|
||||
get => _signalValue;
|
||||
set => SetProperty(ref _signalValue, value);
|
||||
}
|
||||
|
||||
private string _cycleSendInterval;
|
||||
public string CycleSendInterval
|
||||
{
|
||||
get => _cycleSendInterval;
|
||||
set => SetProperty(ref _cycleSendInterval, value);
|
||||
}
|
||||
|
||||
private int _messageSendChannel = 0;
|
||||
public int MessageSendChannel
|
||||
{
|
||||
get => _messageSendChannel;
|
||||
set => SetProperty(ref _messageSendChannel, value);
|
||||
}
|
||||
|
||||
public string BLFPath
|
||||
{
|
||||
get => _systemConfig?.DefaultBLFFilePath ?? "";
|
||||
set
|
||||
{
|
||||
if (_systemConfig != null && _systemConfig.DefaultBLFFilePath != value)
|
||||
{
|
||||
_systemConfig.DefaultBLFFilePath = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string DBCPath
|
||||
{
|
||||
get => _systemConfig?.DefaultDBCFilePath ?? "";
|
||||
set
|
||||
{
|
||||
if (_systemConfig != null && _systemConfig.DefaultDBCFilePath != value)
|
||||
{
|
||||
_systemConfig.DefaultDBCFilePath = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _IsSaved;
|
||||
public bool IsSaved
|
||||
{
|
||||
get => _IsSaved;
|
||||
set => SetProperty(ref _IsSaved, value);
|
||||
}
|
||||
|
||||
public ObservableCollection<AutoDBCLoadItem> DBCAutoLoadList
|
||||
{
|
||||
get => _systemConfig?.DBCAutoLoadList ?? new ObservableCollection<AutoDBCLoadItem>();
|
||||
}
|
||||
|
||||
private AutoDBCLoadItem _SelectedDcAutoLoad;
|
||||
public AutoDBCLoadItem SelectedDcAutoLoad
|
||||
{
|
||||
get => _SelectedDcAutoLoad;
|
||||
set => SetProperty(ref _SelectedDcAutoLoad, value);
|
||||
}
|
||||
|
||||
// ===== 自定义报文发送属性 =====
|
||||
private APP_CHANNEL[] _appChannelNames = Enum.GetValues<APP_CHANNEL>();
|
||||
public APP_CHANNEL[] APP_CHANNEL
|
||||
{
|
||||
get => _appChannelNames;
|
||||
set => SetProperty(ref _appChannelNames, value);
|
||||
}
|
||||
|
||||
private APP_CHANNEL _aIdxChn;
|
||||
public APP_CHANNEL AIdxChn
|
||||
{
|
||||
get => _aIdxChn;
|
||||
set => SetProperty(ref _aIdxChn, value);
|
||||
}
|
||||
|
||||
private int _aID;
|
||||
public int AID
|
||||
{
|
||||
get => _aID;
|
||||
set => SetProperty(ref _aID, value);
|
||||
}
|
||||
|
||||
private bool _aIsTx;
|
||||
public bool AIsTx
|
||||
{
|
||||
get => _aIsTx;
|
||||
set => SetProperty(ref _aIsTx, value);
|
||||
}
|
||||
|
||||
private bool _aIsExt;
|
||||
public bool AIsExt
|
||||
{
|
||||
get => _aIsExt;
|
||||
set => SetProperty(ref _aIsExt, value);
|
||||
}
|
||||
|
||||
private bool _aIsRemote;
|
||||
public bool AIsRemote
|
||||
{
|
||||
get => _aIsRemote;
|
||||
set => SetProperty(ref _aIsRemote, value);
|
||||
}
|
||||
|
||||
private byte _aDlc;
|
||||
public byte ADLC
|
||||
{
|
||||
get => _aDlc;
|
||||
set => SetProperty(ref _aDlc, value);
|
||||
}
|
||||
|
||||
private byte[] _aDataArray;
|
||||
public byte[] ADataArray
|
||||
{
|
||||
get => _aDataArray;
|
||||
set => SetProperty(ref _aDataArray, value);
|
||||
}
|
||||
|
||||
private bool _aIsFD = true;
|
||||
public bool AIsFD
|
||||
{
|
||||
get => _aIsFD;
|
||||
set => SetProperty(ref _aIsFD, value);
|
||||
}
|
||||
|
||||
private bool _aIsBRS = false;
|
||||
public bool AIsBRS
|
||||
{
|
||||
get => _aIsBRS;
|
||||
set => SetProperty(ref _aIsBRS, value);
|
||||
}
|
||||
|
||||
private bool _AutoSetting = true;
|
||||
public bool AutoSetting
|
||||
{
|
||||
get => _AutoSetting;
|
||||
set => SetProperty(ref _AutoSetting, value);
|
||||
}
|
||||
|
||||
private string _CustomMessage = "[00,11,22,33,AA,BB,CC,DD]";
|
||||
public string CustomMessage
|
||||
{
|
||||
get => _CustomMessage;
|
||||
set => SetProperty(ref _CustomMessage, value);
|
||||
}
|
||||
|
||||
private float _CustomSendCycleInterval = 0.0f;
|
||||
public float CustomSendCycleInterval
|
||||
{
|
||||
get => _CustomSendCycleInterval;
|
||||
set => SetProperty(ref _CustomSendCycleInterval, value);
|
||||
}
|
||||
|
||||
//private bool _UpdateToDB;
|
||||
//public bool UpdateToDB
|
||||
//{
|
||||
// get => _UpdateToDB;
|
||||
// set => SetProperty(ref _UpdateToDB, value);
|
||||
//}
|
||||
|
||||
// ===== 连接状态 =====
|
||||
private bool _IsDeviceOpened;
|
||||
public bool IsDeviceOpened
|
||||
{
|
||||
get => _IsDeviceOpened;
|
||||
set => SetProperty(ref _IsDeviceOpened, value);
|
||||
}
|
||||
|
||||
private ObservableCollection<int> _ChannelList;
|
||||
public ObservableCollection<int> ChannelList
|
||||
{
|
||||
get => _ChannelList;
|
||||
set => SetProperty(ref _ChannelList, value);
|
||||
}
|
||||
|
||||
private int _SelectedChannel = -1;
|
||||
public int SelectedChannel
|
||||
{
|
||||
get => _SelectedChannel;
|
||||
set
|
||||
{
|
||||
if (_SelectedChannel != value)
|
||||
{
|
||||
_SelectedChannel = value;
|
||||
if (value >= 0 && _canfd != null)
|
||||
{
|
||||
_canfd.初始化并启动通道((uint)value);
|
||||
}
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 命令
|
||||
public ICommand SelectBLFPathCommand { get; set; }
|
||||
public ICommand SaveBLFPathCommand { get; set; }
|
||||
public ICommand StartTranscribeCommand { get; set; }
|
||||
public ICommand EndTranscribeCommand { get; set; }
|
||||
public ICommand ConnectCanCommand { get; set; }
|
||||
public ICommand CloseCanCommand { get; set; }
|
||||
public ICommand ClearCycleCommand { get; set; }
|
||||
public ICommand UpLoadDBCCommand { get; set; }
|
||||
public ICommand ChangeDBCCommand { get; set; }
|
||||
public ICommand LoadDBCCommand { get; set; }
|
||||
public ICommand LoadMessageCommand { get; set; }
|
||||
public ICommand SetAndSendMessageCommand { get; set; }
|
||||
public ICommand DeleteDcAutoLoadCommand { get; set; }
|
||||
public ICommand SendCustomMessageCommand { get; set; }
|
||||
public ICommand LoadCommand { get; set; }
|
||||
#endregion
|
||||
|
||||
public ZLGCANFDViewModel(IContainerProvider containerProvider) : base(containerProvider)
|
||||
{
|
||||
_systemConfig = containerProvider.Resolve<SystemConfig>();
|
||||
_deviceManager = containerProvider.Resolve<DeviceManager>();
|
||||
_canfd = _deviceManager.CANFD;
|
||||
SelectBLFPathCommand = new DelegateCommand(SelectBLFPath);
|
||||
SaveBLFPathCommand = new DelegateCommand(SaveBLFPath);
|
||||
StartTranscribeCommand = new DelegateCommand(StartTranscribe);
|
||||
EndTranscribeCommand = new DelegateCommand(EndTranscribe);
|
||||
ConnectCanCommand = new DelegateCommand(ConnectCan);
|
||||
CloseCanCommand = new DelegateCommand(CloseCan);
|
||||
ClearCycleCommand = new DelegateCommand(ClearCycle);
|
||||
UpLoadDBCCommand = new DelegateCommand(UpLoadDBC);
|
||||
ChangeDBCCommand = new DelegateCommand(ChangeDBC);
|
||||
LoadDBCCommand = new DelegateCommand(LoadDBC);
|
||||
SetAndSendMessageCommand = new DelegateCommand(SetAndSendMessage);
|
||||
LoadMessageCommand = new DelegateCommand(LoadMessage);
|
||||
DeleteDcAutoLoadCommand = new DelegateCommand(DeleteDcAutoLoad);
|
||||
SendCustomMessageCommand = new DelegateCommand(SendCustomMessage);
|
||||
_canfd.OnDbcMessageDecoded += OnDbcMessageDecoded;
|
||||
LoadCommand = new DelegateCommand(Load);
|
||||
}
|
||||
|
||||
#region Dialog 生命周期
|
||||
public override void OnNavigatedTo(NavigationContext navigationContext)
|
||||
{
|
||||
if (_canfd != null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RaisePropertyChanged(nameof(BLFPath));
|
||||
RaisePropertyChanged(nameof(DBCPath));
|
||||
RaisePropertyChanged(nameof(DBCAutoLoadList));
|
||||
}
|
||||
|
||||
public override void OnNavigatedFrom(NavigationContext navigationContext)
|
||||
{
|
||||
if (_canfd != null)
|
||||
{
|
||||
_canfd.OnDbcMessageDecoded -= OnDbcMessageDecoded;
|
||||
}
|
||||
_refreshCts?.Cancel();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 命令处理
|
||||
private void Load()
|
||||
{
|
||||
int maxCh = _canfd?.DBCParser.MaxChannels ?? 4;
|
||||
ChannelList = new ObservableCollection<int>(Enumerable.Range(0, maxCh));
|
||||
}
|
||||
|
||||
private void SendCustomMessage()
|
||||
{
|
||||
if (_canfd == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
ADataArray = 报文转换(CustomMessage);
|
||||
if (ADataArray.Length > byte.MaxValue) throw new Exception("报文数量超过上限!");
|
||||
if (AutoSetting)
|
||||
{
|
||||
ADLC = (byte)ADataArray.Length;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ShowErrorMessageBox($"报文转换失败:{ex.Message}", () => { });
|
||||
return;
|
||||
}
|
||||
|
||||
_canfd.发送自定义报文(
|
||||
(uint)AIdxChn,
|
||||
AID.ToString(),
|
||||
ADataArray,
|
||||
ADLC,
|
||||
AIsExt,
|
||||
AIsFD,
|
||||
AIsBRS);
|
||||
}
|
||||
|
||||
private void DeleteDcAutoLoad()
|
||||
{
|
||||
if (SelectedDcAutoLoad != null)
|
||||
{
|
||||
DBCAutoLoadList.Remove(SelectedDcAutoLoad);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadMessage()
|
||||
{
|
||||
if (_canfd == null) return;
|
||||
|
||||
if (MessageSendChannel >= 0)
|
||||
{
|
||||
var db = _canfd.DBCParser.MsgDatabase;
|
||||
if (MessageSendChannel < db.Count)
|
||||
{
|
||||
Message = new ObservableCollection<string>(
|
||||
db[MessageSendChannel].Select(s => $"[0x{s.msg_id:X}]{s.msg_name}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetAndSendMessage()
|
||||
{
|
||||
if (_canfd == null) return;
|
||||
|
||||
if (int.TryParse(CycleSendInterval, out int sendPeriod) &&
|
||||
double.TryParse(SignalValue, out double SValue) &&
|
||||
MessageSendChannel >= 0)
|
||||
{
|
||||
_channel = (byte)MessageSendChannel;
|
||||
var message = SelectedMessage.Split(']')[1];
|
||||
|
||||
// 通过 DBC 查找帧 ID
|
||||
var db = _canfd.DBCParser.MsgDatabase;
|
||||
if (MessageSendChannel < db.Count)
|
||||
{
|
||||
var targetMsg = db[MessageSendChannel]
|
||||
.FirstOrDefault(x => $"[0x{x.msg_id:X}]{x.msg_name}" == SelectedMessage);
|
||||
|
||||
if (targetMsg != null)
|
||||
{
|
||||
_canfd.设置报文((uint)MessageSendChannel, targetMsg.msg_id.ToString(), SelectedSignal, SValue, sendPeriod, IsDirectlySend);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpLoadDBC()
|
||||
{
|
||||
if (_canfd == null) return;
|
||||
|
||||
// 释放当前通道的 DBC
|
||||
if (DBCChannel >= 0)
|
||||
{
|
||||
_canfd.释放通道DBC((uint)DBCChannel);
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeDBC()
|
||||
{
|
||||
var dialog = new OpenFileDialog
|
||||
{
|
||||
Title = "更换DBC文件",
|
||||
Filter = "DBC 文件 (*.dbc)|*.dbc|所有文件 (*.*)|*.*",
|
||||
DefaultExt = ".dbc",
|
||||
};
|
||||
if (dialog.ShowDialog() == true)
|
||||
{
|
||||
DBCPath = System.IO.Path.GetFullPath(dialog.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadDBC()
|
||||
{
|
||||
if (_canfd == null || DBCChannel < 0) return;
|
||||
|
||||
bool re = _canfd.加载通道DBC文件((uint)DBCChannel, DBCPath);
|
||||
|
||||
if (re && IsSaved)
|
||||
{
|
||||
var item = DBCAutoLoadList.FirstOrDefault(s => s.DBCChannel == DBCChannel);
|
||||
if (item == null)
|
||||
{
|
||||
DBCAutoLoadList.Add(new AutoDBCLoadItem
|
||||
{
|
||||
DBCFilePath = DBCPath,
|
||||
DBCChannel = DBCChannel
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
DBCAutoLoadList.Remove(item);
|
||||
DBCAutoLoadList.Add(new AutoDBCLoadItem
|
||||
{
|
||||
DBCFilePath = DBCPath,
|
||||
DBCChannel = DBCChannel
|
||||
});
|
||||
}
|
||||
ConfigService.Save(_systemConfig);
|
||||
}
|
||||
}
|
||||
private void ClearCycle()
|
||||
{
|
||||
_canfd?.停止所有循环发送();
|
||||
}
|
||||
|
||||
private void CloseCan()
|
||||
{
|
||||
if (_canfd == null) return;
|
||||
|
||||
_canfd.关闭CAN卡设备();
|
||||
IsDeviceOpened = false;
|
||||
_refreshCts?.Cancel();
|
||||
}
|
||||
|
||||
private void ConnectCan()
|
||||
{
|
||||
if (_canfd == null) return;
|
||||
|
||||
bool re = _canfd.打开设备();
|
||||
IsDeviceOpened = re;
|
||||
|
||||
if (re)
|
||||
{
|
||||
// 启动实时报文刷新
|
||||
_refreshCts?.Cancel();
|
||||
_refreshCts = new CancellationTokenSource();
|
||||
_ = Refresh(_refreshCts.Token);
|
||||
}
|
||||
}
|
||||
|
||||
private void EndTranscribe()
|
||||
{
|
||||
// TODO: BLF 录制功能在 ZLGCANFD 中未实现,暂不支持
|
||||
ShowInfoMessageBox("BLF 录制功能尚未在此硬件驱动中实现。", () => { });
|
||||
}
|
||||
|
||||
private void StartTranscribe()
|
||||
{
|
||||
// TODO: BLF 录制功能在 ZLGCANFD 中未实现,暂不支持
|
||||
ShowInfoMessageBox("BLF 录制功能尚未在此硬件驱动中实现。", () => { });
|
||||
}
|
||||
|
||||
private void SaveBLFPath()
|
||||
{
|
||||
// 路径已直接绑定到 SystemConfig,无需额外操作
|
||||
}
|
||||
|
||||
private void SelectBLFPath()
|
||||
{
|
||||
var dialog = new SaveFileDialog
|
||||
{
|
||||
Title = "保存 CAN报文回放 BLF 文件",
|
||||
Filter = "BLF 文件 (*.blf)|*.blf|所有文件 (*.*)|*.*",
|
||||
DefaultExt = ".blf",
|
||||
FileName = "log.blf",
|
||||
OverwritePrompt = true
|
||||
};
|
||||
if (dialog.ShowDialog() == true)
|
||||
{
|
||||
BLFPath = System.IO.Path.GetFullPath(dialog.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 辅助方法
|
||||
public byte[] 报文转换(string s)
|
||||
{
|
||||
s = s.Replace("[", string.Empty).Replace("]", string.Empty);
|
||||
var strs = s.Split(',', StringSplitOptions.RemoveEmptyEntries);
|
||||
byte[] bytes = new byte[strs.Length];
|
||||
for (int i = 0; i < strs.Length; i++)
|
||||
{
|
||||
bytes[i] = Convert.ToByte(strs[i], 16);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private async Task Refresh(CancellationToken ct = default)
|
||||
{
|
||||
while (!ct.IsCancellationRequested)
|
||||
{
|
||||
// 通过 OnDbcMessageDecoded 事件已实时更新 CanMessageList
|
||||
// 此处仅做周期性 UI 刷新触发
|
||||
await Task.Delay(50, ct);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDbcMessageDecoded(uint channel, ZDBC.DBCMessage msg)
|
||||
{
|
||||
// DBC 解码后的报文回调
|
||||
Application.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
var msgName = System.Text.Encoding.Default.GetString(msg.strName).TrimEnd('\0');
|
||||
var find = CanMessageList.FirstOrDefault(s => s.报文ID == (int)msg.nID&& s.通道==channel);
|
||||
if (find != null)
|
||||
{
|
||||
find.通道 = (byte)channel;
|
||||
find.报文ID = (int)msg.nID;
|
||||
find.时间戳 = (ulong)DateTimeOffset.Now.ToUnixTimeMilliseconds(); ;
|
||||
find.长度 = (byte)msg.nSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
CanMessageList.Add(new CanMessageShowVM
|
||||
{
|
||||
通道 = (byte)channel,
|
||||
报文ID = (int)msg.nID,
|
||||
时间戳 = (ulong)DateTimeOffset.Now.ToUnixTimeMilliseconds(),
|
||||
长度 = (byte)msg.nSize
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private string 十六进制字符串转换(System.Span<byte> s)
|
||||
{
|
||||
if (s == null || s.Length == 0)
|
||||
return "[]";
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.Append('[');
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
{
|
||||
sb.Append("0x");
|
||||
sb.Append(s[i].ToString("X2"));
|
||||
if (i < s.Length - 1)
|
||||
sb.Append(", ");
|
||||
}
|
||||
sb.Append(']');
|
||||
return sb.ToString();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
<UserControl x:Class="CANModule.Views.ZLGCANFDView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
<UserControl x:Class="CANModule.Views.CANView"
|
||||
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:local="clr-namespace:CANModule.Views"
|
||||
xmlns:oxy="http://oxyplot.org/wpf"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:local="clr-namespace:CANModule.Views"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
mc:Ignorable="d"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
@@ -17,16 +18,11 @@
|
||||
<Style BasedOn="{StaticResource DialogUserManageStyle}"
|
||||
TargetType="Window" />
|
||||
</prism:Dialog.WindowStyle>
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="Loaded">
|
||||
<i:InvokeCommandAction Command="{Binding LoadCommand}" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
<UserControl.Resources>
|
||||
<cons:HexConverter x:Key="HexConverter" />
|
||||
</UserControl.Resources>
|
||||
<GroupBox Padding="0,0,0,0"
|
||||
>
|
||||
MouseLeftButtonDown="MouseLeftButtonDown">
|
||||
<GroupBox.Header>
|
||||
<Grid Margin="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
@@ -38,59 +34,46 @@
|
||||
Foreground="White"
|
||||
VerticalAlignment="Center"
|
||||
Margin="5,0,10,0" />
|
||||
|
||||
<Button Content="关闭"
|
||||
Grid.Column="2"
|
||||
Margin="150 0 0 0"
|
||||
Width="60"
|
||||
Command="{Binding CloseCommand}"
|
||||
Height="25" />
|
||||
</Grid>
|
||||
</GroupBox.Header>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="829*" />
|
||||
<ColumnDefinition Width="69*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- CAN卡连接 -->
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Margin="5"
|
||||
Grid.Row="0">
|
||||
<Button Content="打开设备"
|
||||
Command="{Binding ConnectCanCommand}"
|
||||
Margin="5" />
|
||||
<Button Content="关闭设备"
|
||||
Command="{Binding CloseCanCommand}"
|
||||
Margin="5" />
|
||||
<Button Content="清空循环发送报文"
|
||||
Command="{Binding ClearCycleCommand}"
|
||||
Margin="5" />
|
||||
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Margin="5"
|
||||
Grid.Row="1">
|
||||
<Label Content="选择通道初始化(选择前先打开设备)"
|
||||
VerticalAlignment="Center" />
|
||||
<ComboBox SelectedItem="{Binding SelectedChannel}"
|
||||
ItemsSource="{Binding ChannelList}"
|
||||
materialDesign:HintAssist.Hint=""
|
||||
MinWidth="80"
|
||||
Margin="5"
|
||||
VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
<TreeView Grid.Row="2">
|
||||
<!-- TreeView 用于显示不同选项 -->
|
||||
<TreeView Grid.Row="1"
|
||||
Grid.ColumnSpan="2">
|
||||
<!-- 调试选项 -->
|
||||
<TreeViewItem Header="调试选项">
|
||||
<Button Content="初始化TSMaster"
|
||||
Command="{Binding InitTSMasterCommand}"
|
||||
CommandParameter="初始化TSMaster" />
|
||||
<Button Content="释放TSMaster"
|
||||
Command="{Binding ReleaseTSMasterCommand}"
|
||||
CommandParameter="释放TSMaster" />
|
||||
|
||||
</TreeViewItem>
|
||||
|
||||
<!-- 监视选项 -->
|
||||
<TreeViewItem Header="监视">
|
||||
<DataGrid x:Name="表格"
|
||||
Width="550"
|
||||
Height="350"
|
||||
<DataGrid x:Name="表格" Width="800"
|
||||
Height="450"
|
||||
VirtualizingPanel.IsVirtualizing="True"
|
||||
IsReadOnly="True"
|
||||
AutoGenerateColumns="False"
|
||||
ItemsSource="{Binding CanMessageList, Mode=OneWay}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="通道" Binding="{Binding 通道}" Width="90" />
|
||||
<DataGridTextColumn Header="报文ID" Binding="{Binding 报文ID, Converter={StaticResource HexConverter}}" Width="150" />
|
||||
<DataGridTextColumn Header="长度" Binding="{Binding 长度}" Width="90" />
|
||||
<DataGridTextColumn Header="时间戳" Binding="{Binding 时间戳}" Width="Auto" />
|
||||
</DataGrid.Columns>
|
||||
|
||||
</DataGrid>
|
||||
</TreeViewItem>
|
||||
|
||||
@@ -98,11 +81,13 @@
|
||||
<TreeViewItem Header="DBC">
|
||||
<Label Content="请注意,要在断开CAN卡的情况下才能操作DBC!"
|
||||
Foreground="Red" />
|
||||
<Button Content="卸载当前通道DBC"
|
||||
Command="{Binding UpLoadDBCCommand}" />
|
||||
<Button Content="卸载所有DBC"
|
||||
Command="{Binding UpLoadDBCCommand}"
|
||||
CommandParameter="卸载DBC" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Content="更换DBC"
|
||||
Command="{Binding ChangeDBCCommand}" />
|
||||
Command="{Binding ChangeDBCCommand}"
|
||||
CommandParameter="更换DBC" />
|
||||
<Label Content="DBC文件路径"
|
||||
VerticalContentAlignment="Center" />
|
||||
<TextBox Text="{Binding DBCPath,Mode=TwoWay}"
|
||||
@@ -112,7 +97,8 @@
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Content="加载DBC"
|
||||
Command="{Binding LoadDBCCommand}" />
|
||||
Command="{Binding LoadDBCCommand}"
|
||||
CommandParameter="加载DBC" />
|
||||
<Label Content="通道(从0开始)"
|
||||
VerticalContentAlignment="Center" />
|
||||
<TextBox Text="{Binding DBCChannel,Mode=TwoWay}"
|
||||
@@ -145,28 +131,27 @@
|
||||
</ContextMenu>
|
||||
</DataGrid.ContextMenu>
|
||||
</DataGrid>
|
||||
<Button Content="查看DBC"
|
||||
Command="{Binding CheckDBCCommand}"
|
||||
CommandParameter="查看DBC" />
|
||||
</TreeViewItem>
|
||||
|
||||
<!-- CAN卡连接选项 -->
|
||||
<TreeViewItem Header="CAN卡连接">
|
||||
<Button Content="连接"
|
||||
Command="{Binding ConnectCanCommand}"
|
||||
CommandParameter="连接" />
|
||||
<Button Content="断开"
|
||||
Command="{Binding CloseCanCommand}"
|
||||
CommandParameter="断开" />
|
||||
<Button Content="清空循环发送报文"
|
||||
Command="{Binding ClearCycleCommand}"
|
||||
CommandParameter="清空循环发送报文" />
|
||||
|
||||
</TreeViewItem>
|
||||
|
||||
<!-- DBC报文发送 -->
|
||||
<TreeViewItem Header="DBC报文发送">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label Content="通道(从0开始)"
|
||||
VerticalContentAlignment="Center" />
|
||||
<ComboBox SelectedValue="{Binding MessageSendChannel}"
|
||||
SelectedValuePath="Content"
|
||||
materialDesign:HintAssist.Hint=""
|
||||
MinWidth="60"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,5,5,5">
|
||||
<ComboBoxItem Content="0"/>
|
||||
<ComboBoxItem Content="1"/>
|
||||
<ComboBoxItem Content="2"/>
|
||||
<ComboBoxItem Content="3"/>
|
||||
</ComboBox>
|
||||
<Button Content="加载报文"
|
||||
Command="{Binding LoadMessageCommand}"
|
||||
Margin="5" />
|
||||
</StackPanel>
|
||||
<DockPanel>
|
||||
<Label Content="报文" />
|
||||
<ComboBox MinWidth="100"
|
||||
@@ -194,21 +179,33 @@
|
||||
MinWidth="100" />
|
||||
</DockPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label Content="通道(从0开始)"
|
||||
VerticalContentAlignment="Center" />
|
||||
<TextBox Text="{Binding MessageSendChannel}"
|
||||
materialDesign:HintAssist.Hint=""
|
||||
MinWidth="100"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,10,10,10" />
|
||||
<Button Content="加载报文"
|
||||
Command="{Binding LoadMessageCommand}"
|
||||
CommandParameter="加载报文"
|
||||
Margin="10" />
|
||||
<Button Content="设置信号并发送"
|
||||
Command="{Binding SetAndSendMessageCommand}" />
|
||||
Command="{Binding SetAndSendMessageCommand}"
|
||||
CommandParameter="设置" />
|
||||
<CheckBox Content="直接发送"
|
||||
IsChecked="{Binding IsDirectlySend}" />
|
||||
</StackPanel>
|
||||
</TreeViewItem>
|
||||
|
||||
<!-- 自定义报文发送 -->
|
||||
<TreeViewItem Header="自定义报文发送">
|
||||
<DockPanel>
|
||||
<Label Content="通道" />
|
||||
<ComboBox MinWidth="100"
|
||||
materialDesign:HintAssist.Hint=""
|
||||
SelectedItem="{Binding AIdxChn}"
|
||||
ItemsSource="{Binding APP_CHANNEL}" />
|
||||
ItemsSource="{Binding APP_CHANNEL}"
|
||||
/>
|
||||
</DockPanel>
|
||||
<DockPanel>
|
||||
<Label Content="ID" />
|
||||
@@ -250,10 +247,11 @@
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Content="发送"
|
||||
Command="{Binding SendCustomMessageCommand}" />
|
||||
<!--<CheckBox Margin="10"
|
||||
Command="{Binding SendCustomMessageCommand}"
|
||||
/>
|
||||
<CheckBox Margin="10"
|
||||
Content="更新到数据库"
|
||||
IsChecked="{Binding UpdateToDB}" />-->
|
||||
IsChecked="{Binding UpdateToDB}" />
|
||||
</StackPanel>
|
||||
</TreeViewItem>
|
||||
|
||||
@@ -268,16 +266,20 @@
|
||||
VerticalContentAlignment="Center" />
|
||||
<Button Content="选择路径"
|
||||
Margin="10 0"
|
||||
Command="{Binding SelectBLFPathCommand}" />
|
||||
Command="{Binding SelectBLFPathCommand}"
|
||||
CommandParameter="选择路径" />
|
||||
<Button Content="保存路径"
|
||||
Command="{Binding SaveBLFPathCommand}" />
|
||||
Command="{Binding SaveBLFPathCommand}"
|
||||
CommandParameter="保存路径" />
|
||||
</DockPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Content="开始录制"
|
||||
Command="{Binding StartTranscribeCommand}" />
|
||||
Command="{Binding StartTranscirbeCommand}"
|
||||
CommandParameter="开始录制" />
|
||||
<Button Content="结束录制"
|
||||
Margin="10 0"
|
||||
Command="{Binding EndTranscribeCommand}" />
|
||||
Command="{Binding EndTranscirbeCommand}"
|
||||
CommandParameter="结束录制" />
|
||||
</StackPanel>
|
||||
</TreeViewItem>
|
||||
</TreeView>
|
||||
@@ -16,14 +16,15 @@ using System.Windows.Shapes;
|
||||
namespace CANModule.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// ZLGCANFDView.xaml 的交互逻辑
|
||||
/// CANView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ZLGCANFDView : UserControl
|
||||
public partial class CANView : UserControl
|
||||
{
|
||||
public ZLGCANFDView()
|
||||
public CANView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
@@ -31,5 +32,7 @@ namespace CANModule.Views
|
||||
Window.GetWindow(this)?.DragMove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,27 @@
|
||||
<UserControl x:Class="CANModule.Views.CollectCANSignalSettingView"
|
||||
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:local="clr-namespace:CANModule.Views"
|
||||
xmlns:oxy="http://oxyplot.org/wpf"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
mc:Ignorable="d"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
xmlns:cons="clr-namespace:UIShare.Converters;assembly=UIShare"
|
||||
Background="White"
|
||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||
Height="400"
|
||||
Width="1000">
|
||||
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:oxy="http://oxyplot.org/wpf"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
mc:Ignorable="d"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
xmlns:cons="clr-namespace:UIShare.Converters;assembly=UIShare"
|
||||
Background="White"
|
||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||
Height="400"
|
||||
Width="1000">
|
||||
<prism:Dialog.WindowStyle>
|
||||
<Style BasedOn="{StaticResource DialogUserManageStyle}"
|
||||
TargetType="Window" />
|
||||
</prism:Dialog.WindowStyle>
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="Loaded">
|
||||
<i:InvokeCommandAction Command="{Binding LoadCommand}" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
<UserControl.Resources>
|
||||
<cons:HexConverter x:Key="HexConverter" />
|
||||
</UserControl.Resources>
|
||||
@@ -79,11 +83,12 @@
|
||||
Margin="10">
|
||||
<Label Content="通道(从0开始)"
|
||||
VerticalAlignment="Center" />
|
||||
<TextBox Name="SignalComboBox"
|
||||
Text="{Binding MessageChannel}"
|
||||
<ComboBox Name="SignalComboBox"
|
||||
SelectedItem="{Binding MessageChannel,Mode=TwoWay}"
|
||||
MaxWidth="200"
|
||||
MinWidth="120"
|
||||
Margin="10"
|
||||
ItemsSource="{Binding ChannelList}"
|
||||
VerticalAlignment="Center"
|
||||
materialDesign:HintAssist.Hint="信号通道" />
|
||||
<Label Content="报文"
|
||||
@@ -1,11 +1,22 @@
|
||||
using System.Windows;
|
||||
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 CANModule.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// CollectCANSignalSettingView.xaml 的交互逻辑
|
||||
/// CollectCANSignalSetting.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class CollectCANSignalSettingView : UserControl
|
||||
{
|
||||
@@ -1,9 +1,8 @@
|
||||
<UserControl x:Class="CANModule.Views.SelectCanMessageView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
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:local="clr-namespace:CANModule.Views"
|
||||
xmlns:oxy="http://oxyplot.org/wpf"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
@@ -44,26 +43,26 @@
|
||||
Height="25" />
|
||||
</Grid>
|
||||
</GroupBox.Header>
|
||||
<Grid>
|
||||
<StackPanel Grid.Row="1" Margin="10">
|
||||
<Label Content="通道" VerticalAlignment="Center"/>
|
||||
<Grid>
|
||||
<StackPanel Grid.Row="1" Margin="10">
|
||||
<Label Content="通道" VerticalAlignment="Center"/>
|
||||
<ComboBox ItemsSource="{Binding ChannelList}"
|
||||
SelectedItem="{Binding MessageChannel,Mode=TwoWay}"
|
||||
MinWidth="100"
|
||||
VerticalAlignment="Center"
|
||||
materialDesign:HintAssist.Hint="" />
|
||||
<Label Content="报文" VerticalAlignment="Center"/>
|
||||
<Label Content="报文" VerticalAlignment="Center"/>
|
||||
<ComboBox materialDesign:HintAssist.Hint=""
|
||||
MinWidth="100"
|
||||
SelectedItem="{Binding SelectedMessage,Mode=TwoWay}"
|
||||
ItemsSource="{Binding MessageList}" />
|
||||
<Label Content="信号" VerticalAlignment="Center"/>
|
||||
<Label Content="信号" VerticalAlignment="Center"/>
|
||||
<ComboBox materialDesign:HintAssist.Hint=""
|
||||
SelectedItem="{Binding SelectedSignal,Mode=TwoWay}"
|
||||
ItemsSource="{Binding SignalList}" MinWidth="100" />
|
||||
<Button Content="选择报文名" Margin="10" Command="{Binding GetSelectedMessageCommand}"/>
|
||||
<Button Content="选择报文名" Margin="10" Command="{Binding GetSelectedMessageCommand}"/>
|
||||
<Button Content="选择信号名" Margin="10" Command="{Binding GetSelectedSignalCommand}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
</UserControl>
|
||||
</UserControl>
|
||||
|
||||
Reference in New Issue
Block a user