From 9d1660270272180cd71147d6ddd53d1382643d2e Mon Sep 17 00:00:00 2001
From: wenxiangchao <wenxiangchao@ihengxin.com.cn>
Date: 星期一, 02 十一月 2026 18:00:14 +0800
Subject: [PATCH] merge: 并入远程 Initial commit 作为历史根节点
---
Plugin.DeviceConfig/DeviceEditModal.xaml.cs | 368 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 368 insertions(+), 0 deletions(-)
diff --git a/Plugin.DeviceConfig/DeviceEditModal.xaml.cs b/Plugin.DeviceConfig/DeviceEditModal.xaml.cs
new file mode 100644
index 0000000..9113dca
--- /dev/null
+++ b/Plugin.DeviceConfig/DeviceEditModal.xaml.cs
@@ -0,0 +1,368 @@
+using HMI.UI.Util;
+using Panuon.WPF.UI;
+using Plugin.DeviceConfig.Entity;
+using Plugin.DeviceConfig.Model;
+using System;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Plugin.DeviceConfig
+{
+ /// <summary>
+ /// DeviceEditModal.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class DeviceEditModal : WindowX
+ {
+ private DeviceConfigModel _model;
+ private DeviceDefinition _device;
+ private ObservableCollection<DeviceChannel> _channels = new();
+ private bool _isNew;
+
+ public DeviceEditModal()
+ {
+ DataContext = this;
+ InitializeComponent();
+ }
+
+ /// <summary>
+ /// 鎵撳紑寮圭獥
+ /// </summary>
+ public bool? Open(DeviceDefinition device, DeviceConfigModel model)
+ {
+ _model = model;
+ _device = device;
+ _isNew = string.IsNullOrEmpty(device.DeviceId);
+
+ // 鍒濆鍖栨灇涓句笅鎷�
+ cbKind.ItemsSource = Enum.GetValues(typeof(DeviceKind)).Cast<DeviceKind>().ToList();
+ cbTransport.ItemsSource = Enum.GetValues(typeof(TransportType)).Cast<TransportType>().ToList();
+ cbTransport.SelectionChanged += CbTransport_SelectionChanged;
+
+ // 濉厖鏁版嵁
+ tbDeviceId.Text = device.DeviceId;
+ tbDeviceId.IsReadOnly = !_isNew;
+ cbKind.SelectedItem = device.Kind;
+ tbDriverType.Text = device.DriverType;
+ cbTransport.SelectedItem = device.Transport;
+ tbEndpoint.Text = device.Endpoint;
+
+ // 榛樿椹卞姩绫诲瀷寤鸿 & 绔偣鎻愮ず
+ UpdateDriverHint();
+ UpdateEndpointHint();
+
+ // 鍔犺浇閫氶亾
+ if (!_isNew && !string.IsNullOrEmpty(device.DeviceId))
+ {
+ var chList = _model.GetChannelsByDevice(device.DeviceId);
+ _channels = new ObservableCollection<DeviceChannel>(chList);
+ }
+ else
+ {
+ _channels = new ObservableCollection<DeviceChannel>();
+ }
+ channelListView.ItemsSource = _channels;
+
+ return ShowDialog();
+ }
+
+ #region 閫氶亾鎿嶄綔
+
+ private void AddChannel_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ if (!int.TryParse(tbChId.Text, out int chId) || chId < 0)
+ {
+ ToastHelper.Warning("璇疯緭鍏ユ湁鏁堢殑閫氶亾缂栧彿锛堥潪璐熸暣鏁帮級");
+ return;
+ }
+ if (_channels.Any(c => c.ChannelId == chId))
+ {
+ ToastHelper.Warning($"閫氶亾 {chId} 宸插瓨鍦�");
+ return;
+ }
+
+ double.TryParse(tbChVolt.Text, out double volt);
+ double.TryParse(tbChCurr.Text, out double curr);
+
+ var ch = new DeviceChannel
+ {
+ DeviceId = _device.DeviceId ?? tbDeviceId.Text,
+ ChannelId = chId,
+ Capability = tbChCap.Text ?? string.Empty,
+ MaxVoltage = volt,
+ MaxCurrent = curr,
+ };
+ _channels.Add(ch);
+ ClearChannelInputs();
+ }
+ catch (Exception ex)
+ {
+ ToastHelper.Error($"鏂板閫氶亾澶辫触: {ex.Message}");
+ }
+ }
+
+ private void EditChannel_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ if (sender is Button btn && btn.Tag is DeviceChannel ch)
+ {
+ tbChId.Text = ch.ChannelId.ToString();
+ tbChCap.Text = ch.Capability;
+ tbChVolt.Text = ch.MaxVoltage.ToString("F2");
+ tbChCurr.Text = ch.MaxCurrent.ToString("F2");
+ }
+ }
+ catch (Exception ex)
+ {
+ ToastHelper.Error($"鍔犺浇閫氶亾鏁版嵁澶辫触: {ex.Message}");
+ }
+ }
+
+ private void DeleteChannel_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ if (sender is Button btn && btn.Tag is DeviceChannel ch)
+ {
+ if (MsgBoxHelper.WarnMessage(this, $"纭畾瑕佸垹闄ら�氶亾 {ch.ChannelId} 鍚楋紵") == MessageBoxResult.OK)
+ {
+ _channels.Remove(ch);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ ToastHelper.Error($"鍒犻櫎閫氶亾澶辫触: {ex.Message}");
+ }
+ }
+
+ private void SaveChannel_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ if (!int.TryParse(tbChId.Text, out int chId) || chId < 0)
+ {
+ ToastHelper.Warning("璇疯緭鍏ユ湁鏁堢殑閫氶亾缂栧彿");
+ return;
+ }
+
+ double.TryParse(tbChVolt.Text, out double volt);
+ double.TryParse(tbChCurr.Text, out double curr);
+
+ var existing = _channels.FirstOrDefault(c => c.ChannelId == chId);
+ if (existing != null)
+ {
+ existing.Capability = tbChCap.Text ?? string.Empty;
+ existing.MaxVoltage = volt;
+ existing.MaxCurrent = curr;
+ }
+ else
+ {
+ _channels.Add(new DeviceChannel
+ {
+ DeviceId = _device.DeviceId ?? tbDeviceId.Text,
+ ChannelId = chId,
+ Capability = tbChCap.Text ?? string.Empty,
+ MaxVoltage = volt,
+ MaxCurrent = curr,
+ });
+ }
+ ClearChannelInputs();
+ ToastHelper.Success("閫氶亾宸蹭繚瀛�");
+ }
+ catch (Exception ex)
+ {
+ ToastHelper.Error($"淇濆瓨閫氶亾澶辫触: {ex.Message}");
+ }
+ }
+
+ private void DelChannel_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ var selected = channelListView.SelectedItem as DeviceChannel;
+ if (selected == null)
+ {
+ ToastHelper.Warning("璇峰厛閫変腑瑕佸垹闄ょ殑閫氶亾");
+ return;
+ }
+ if (MsgBoxHelper.WarnMessage(this, $"纭畾瑕佸垹闄ら�氶亾 {selected.ChannelId} 鍚楋紵") == MessageBoxResult.OK)
+ {
+ _channels.Remove(selected);
+ }
+ }
+ catch (Exception ex)
+ {
+ ToastHelper.Error($"鍒犻櫎閫氶亾澶辫触: {ex.Message}");
+ }
+ }
+
+ private void ClearChannelInputs()
+ {
+ tbChId.Text = string.Empty;
+ tbChCap.Text = string.Empty;
+ tbChVolt.Text = string.Empty;
+ tbChCurr.Text = string.Empty;
+ }
+
+ #endregion
+
+ #region 淇濆瓨/鍙栨秷
+
+ private void SaveBtn_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ // 楠岃瘉
+ var deviceId = tbDeviceId.Text?.Trim();
+ if (string.IsNullOrEmpty(deviceId))
+ {
+ ToastHelper.Warning("璁惧ID涓嶈兘涓虹┖");
+ return;
+ }
+
+ if (cbKind.SelectedItem is not DeviceKind kind)
+ {
+ ToastHelper.Warning("璇烽�夋嫨璁惧绫诲瀷");
+ return;
+ }
+
+ if (cbTransport.SelectedItem is not TransportType transport)
+ {
+ ToastHelper.Warning("璇烽�夋嫨浼犺緭鏂瑰紡");
+ return;
+ }
+
+ var endpoint = tbEndpoint.Text?.Trim();
+ if (string.IsNullOrEmpty(endpoint))
+ {
+ ToastHelper.Warning("杩炴帴绔偣涓嶈兘涓虹┖");
+ return;
+ }
+
+ // 楠岃瘉 Endpoint 鏍煎紡
+ if (transport == TransportType.Tcp)
+ {
+ if (!endpoint.Contains(":") && !endpoint.Contains("."))
+ {
+ ToastHelper.Warning("TCP绔偣鏍煎紡涓嶆纭紝搴斾负 IP:Port 鏍煎紡");
+ return;
+ }
+ }
+ else if (transport == TransportType.Can)
+ {
+ // CAN 绔偣鏍煎紡锛氭�荤嚎鍚嶇О:鑺傜偣缂栧彿 濡� "CAN_BUS_1:0"
+ var parts = endpoint.Split(':');
+ if (parts.Length != 2 || string.IsNullOrWhiteSpace(parts[0]) || !int.TryParse(parts[1], out int nodeIdx) || nodeIdx < 0)
+ {
+ ToastHelper.Warning("CAN绔偣鏍煎紡涓嶆纭紝搴斾负 鎬荤嚎鍚嶇О:鑺傜偣缂栧彿锛堝 CAN_BUS_1:0锛�");
+ return;
+ }
+ }
+
+ // 妫�鏌� DeviceId 鏄惁閲嶅锛堟柊澧炴椂锛�
+ if (_isNew)
+ {
+ var existing = _model.GetDeviceById(deviceId);
+ if (existing != null)
+ {
+ ToastHelper.Warning($"璁惧ID [{deviceId}] 宸插瓨鍦�");
+ return;
+ }
+ }
+
+ // 淇濆瓨璁惧
+ _device.DeviceId = deviceId;
+ _device.Kind = kind;
+ _device.DriverType = tbDriverType.Text?.Trim() ?? string.Empty;
+ _device.Transport = transport;
+ _device.Endpoint = endpoint;
+
+ _model.SaveDevice(_device);
+
+ // 淇濆瓨閫氶亾
+ foreach (var ch in _channels)
+ {
+ ch.DeviceId = deviceId;
+ _model.SaveChannel(ch);
+ }
+
+ DialogResult = true;
+ Close();
+ }
+ catch (Exception ex)
+ {
+ ToastHelper.Error($"淇濆瓨澶辫触: {ex.Message}");
+ }
+ }
+
+ private void CancelBtn_Click(object sender, RoutedEventArgs e)
+ {
+ DialogResult = false;
+ Close();
+ }
+
+ private void CbTransport_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ UpdateEndpointHint();
+ }
+
+ /// <summary>
+ /// 鏍规嵁浼犺緭鏂瑰紡鏇存柊绔偣杈撳叆妗嗘彁绀�
+ /// </summary>
+ private void UpdateEndpointHint()
+ {
+ if (cbTransport.SelectedItem is TransportType tt)
+ {
+ switch (tt)
+ {
+ case TransportType.Can:
+ Panuon.WPF.UI.TextBoxHelper.SetWatermark(tbEndpoint, "CAN鎬荤嚎绔偣锛屾牸寮�: 鎬荤嚎鍚嶇О:鑺傜偣缂栧彿锛堝 CAN_BUS_1:0锛�");
+ break;
+ case TransportType.Serial:
+ Panuon.WPF.UI.TextBoxHelper.SetWatermark(tbEndpoint, "涓插彛鍙凤紝濡� COM3:115200:8:N:1");
+ break;
+ case TransportType.Visa:
+ Panuon.WPF.UI.TextBoxHelper.SetWatermark(tbEndpoint, "VISG 鍦板潃锛屽 TCPIP0::192.168.1.100::inst0::INSTR");
+ break;
+ case TransportType.SDK:
+ Panuon.WPF.UI.TextBoxHelper.SetWatermark(tbEndpoint, "SDK 璁惧鏍囪瘑锛屽 SDK://DeviceName/Instance");
+ break;
+ default:
+ Panuon.WPF.UI.TextBoxHelper.SetWatermark(tbEndpoint, "渚�: 192.168.10.124:30000 鎴� COM3");
+ break;
+ }
+ }
+ }
+
+ /// <summary>
+ /// 鏍规嵁璁惧绫诲瀷寤鸿榛樿椹卞姩绫诲瀷
+ /// </summary>
+ private void UpdateDriverHint()
+ {
+ // 淇濈暀鐜版湁椹卞姩绫诲瀷锛屼笉鑷姩淇敼銆備粎褰撲负绌烘椂鎻愮ず榛樿鍊�
+ if (string.IsNullOrWhiteSpace(tbDriverType.Text) && cbKind.SelectedItem is DeviceKind kind)
+ {
+ string hint = kind switch
+ {
+ DeviceKind.CanDevice => "CAN",
+ DeviceKind.PowerSupply => "SCPI",
+ DeviceKind.PlcDevice => "S7",
+ DeviceKind.Chamber => "Tcp",
+ DeviceKind.DAQ => "Tcp",
+ _ => ""
+ };
+ if (!string.IsNullOrEmpty(hint))
+ {
+ tbDriverType.Text = hint;
+ }
+ }
+ }
+
+ #endregion
+ }
+}
--
Gitblit v1.9.1