报文设置扩展

This commit is contained in:
hsc
2026-07-06 09:28:29 +08:00
parent 2820b2f300
commit 6c2b975999
12 changed files with 527 additions and 15 deletions

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\UIShare\UIShare.csproj" />
</ItemGroup>
</Project>

View File

@@ -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>("SelectCanMessageView");
}
}
}

View File

@@ -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<int> _ChannelList;
public ObservableCollection<int> ChannelList
{
get => _ChannelList;
set => SetProperty(ref _ChannelList, value);
}
private ObservableCollection<string> _messageList;
public ObservableCollection<string> MessageList
{
get => _messageList;
set => SetProperty(ref _messageList, value);
}
private ObservableCollection<string> _signalList;
public ObservableCollection<string> 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<string>(targetMsg.signal_Name);
}
else
{
SignalList = new ObservableCollection<string>();
}
}
else
{
SignalList = new ObservableCollection<string>();
}
}
}
}
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<string>();
// 2. 刷新当前通道的报文列表
if (ZLGDBCParser.MsgDatabase != null && ZLGDBCParser.MsgDatabase.Count > value)
{
MessageList = new ObservableCollection<string>(
ZLGDBCParser.MsgDatabase[value].Select(s => $"[0x{s.msg_id:X}]{s.msg_name}")
);
}
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)
{
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<int>(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
}
}

View File

@@ -0,0 +1,69 @@
<UserControl x:Class="CANModule.Views.SelectCanMessageView"
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="350"
Width="350">
<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>
<GroupBox Padding="0,0,0,0"
MouseLeftButtonDown="MouseLeftButtonDown">
<GroupBox.Header>
<Grid Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="*" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Text="CAN报文选择"
Foreground="White"
VerticalAlignment="Center"
Margin="5,0,10,0" />
<Button Content="关闭"
Grid.Column="2"
Margin="0 0 0 0"
Width="60"
Command="{Binding CloseCommand}"
Height="25" />
</Grid>
</GroupBox.Header>
<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"/>
<ComboBox materialDesign:HintAssist.Hint=""
MinWidth="100"
SelectedItem="{Binding SelectedMessage,Mode=TwoWay}"
ItemsSource="{Binding MessageList}" />
<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 GetSelectedSignalCommand}"/>
</StackPanel>
</Grid>
</GroupBox>
</UserControl>

View File

@@ -0,0 +1,36 @@
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>
/// SelectCanMessageView.xaml 的交互逻辑
/// </summary>
public partial class SelectCanMessageView : UserControl
{
public SelectCanMessageView()
{
InitializeComponent();
}
private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Window.GetWindow(this)?.DragMove();
}
}
}
}