| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- using System;
- using System.Collections.Specialized;
- using System.Linq;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Media;
- using TeamAAS.Communication.Base;
- using TeamAAS.Communication.Interfaces;
- namespace TeamAAS.Communication.UI
- {
- /// <summary>
- /// 默认通讯调试页:按设备类型自适应——PLC 设备(PlcCommunicationBase)显示寄存器读写(带数据类型/长度),
- /// 其余(串口/文本)显示收发;底部收发/读写日志(双击清空)。
- /// 未在 [Communication] 特性指定 DebugPageType 的设备均用本页。直接操作 BindCommunication 得到的实例。
- /// </summary>
- public partial class DefaultCommunicationDebugPage : UserControl, ICommunicationDebugPage
- {
- private ICommunication _comm;
- private BindableCommunicationBase _logDevice;
- public DefaultCommunicationDebugPage()
- {
- InitializeComponent();
- TypeCombo.ItemsSource = Enum.GetValues(typeof(DebugDataType));
- TypeCombo.SelectedItem = DebugDataType.Int;
- IsEnabled = false;
- }
- public void BindCommunication(ICommunication communication)
- {
- UnbindCommunication();
- _comm = communication;
- bool isPlc = communication is PlcCommunicationBase;
- PlcPanel.Visibility = isPlc ? Visibility.Visible : Visibility.Collapsed;
- TextPanel.Visibility = isPlc ? Visibility.Collapsed : Visibility.Visible;
- _logDevice = communication as BindableCommunicationBase;
- LogList.ItemsSource = _logDevice == null ? null : _logDevice.DebugLog;
- if (_logDevice != null)
- _logDevice.DebugLog.CollectionChanged += OnLogChanged;
- IsEnabled = communication != null;
- ScrollLast();
- }
- public void UnbindCommunication()
- {
- if (_logDevice != null)
- _logDevice.DebugLog.CollectionChanged -= OnLogChanged;
- _logDevice = null;
- _comm = null;
- LogList.ItemsSource = null;
- IsEnabled = false;
- }
- private void OnLogChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
- if (e.Action == NotifyCollectionChangedAction.Add)
- Dispatcher.BeginInvoke(new Action(ScrollLast), System.Windows.Threading.DispatcherPriority.Normal);
- }
- private void ScrollLast()
- {
- if (LogList.Items.Count == 0) return;
- var last = LogList.Items[LogList.Items.Count - 1];
- LogList.ScrollIntoView(last);
- var sv = FindScrollViewer(LogList);
- if (sv != null) sv.ScrollToEnd();
- }
- private static ScrollViewer FindScrollViewer(DependencyObject root)
- {
- if (root == null) return null;
- for (int i = 0; i < VisualTreeHelper.GetChildrenCount(root); i++)
- {
- var child = VisualTreeHelper.GetChild(root, i);
- if (child is ScrollViewer) return (ScrollViewer)child;
- var found = FindScrollViewer(child);
- if (found != null) return found;
- }
- return null;
- }
- private void LogList_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
- {
- if (_logDevice != null) _logDevice.DebugLog.Clear();
- }
- private void BtnSend_Click(object sender, RoutedEventArgs e)
- {
- if (_comm == null || string.IsNullOrEmpty(TxtSend.Text)) return;
- try
- {
- _comm.WriteValue(null, TxtSend.Text);
- if (_logDevice != null) _logDevice.AppendLog("TX: " + TxtSend.Text);
- }
- catch (Exception ex)
- {
- if (_logDevice != null) _logDevice.AppendLog("发送失败: " + ex.Message);
- }
- }
- private void BtnRead_Click(object sender, RoutedEventArgs e)
- {
- var plc = _comm as PlcCommunicationBase;
- if (plc == null) return;
- try
- {
- string addr = (TxtAddress.Text ?? "").Trim();
- DebugDataType type = CurrentType;
- ushort len = CurrentLength;
- var result = plc.ReadValue(addr, type, len);
- string lenStr = len > 1 ? (", len=" + len) : "";
- plc.AppendLog("读取 " + addr + " (" + type + lenStr + ") => " + FormatResult(result));
- }
- catch (Exception ex) { plc.AppendLog("读取失败: " + ex.Message); }
- }
- private void BtnWrite_Click(object sender, RoutedEventArgs e)
- {
- var plc = _comm as PlcCommunicationBase;
- if (plc == null) return;
- try
- {
- string addr = (TxtAddress.Text ?? "").Trim();
- DebugDataType type = CurrentType;
- ushort len = CurrentLength;
- object val = ParseDebugValue(TxtWriteValue.Text, type);
- Array arr = val as Array;
- if (arr != null && arr.Length != len)
- {
- plc.AppendLog("写入失败: 数组长度(" + arr.Length + ")与长度设置(" + len + ")不一致");
- return;
- }
- if (arr != null) plc.WriteValue(addr, val, type, len);
- else plc.WriteValue(addr, val, type);
- string lenStr = arr != null ? (", len=" + len) : "";
- plc.AppendLog("写入 " + addr + " (" + type + lenStr + ") = " + FormatResult(val));
- }
- catch (Exception ex) { plc.AppendLog("写入失败: " + ex.Message); }
- }
- private DebugDataType CurrentType
- {
- get
- {
- if (TypeCombo.SelectedItem is DebugDataType) return (DebugDataType)TypeCombo.SelectedItem;
- return DebugDataType.Int;
- }
- }
- private ushort CurrentLength
- {
- get
- {
- int n;
- if (!int.TryParse((TxtLength.Text ?? "").Trim(), out n)) n = 1;
- if (n < 1) n = 1;
- if (n > 100) n = 100;
- return (ushort)n;
- }
- }
- private static string FormatResult(object value)
- {
- if (value == null) return "(null)";
- Array arr = value as Array;
- if (arr != null) return "[" + string.Join(",", arr.Cast<object>()) + "]";
- return value.ToString();
- }
- private static object ParseDebugValue(string text, DebugDataType type)
- {
- if (!string.IsNullOrWhiteSpace(text))
- {
- string t = text.Trim();
- if (t.StartsWith("[") && t.EndsWith("]"))
- {
- string inner = t.Substring(1, t.Length - 2);
- var vals = inner.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
- .Select(p => p.Trim()).Where(p => p.Length > 0).ToArray();
- if (vals.Length > 0)
- {
- switch (type)
- {
- case DebugDataType.Bool: return vals.Select(p => bool.Parse(p)).ToArray();
- case DebugDataType.Byte: return vals.Select(p => byte.Parse(p)).ToArray();
- case DebugDataType.Short: return vals.Select(p => short.Parse(p)).ToArray();
- case DebugDataType.Ushort: return vals.Select(p => ushort.Parse(p)).ToArray();
- case DebugDataType.Int: return vals.Select(p => int.Parse(p)).ToArray();
- case DebugDataType.Uint: return vals.Select(p => uint.Parse(p)).ToArray();
- case DebugDataType.Long: return vals.Select(p => long.Parse(p)).ToArray();
- case DebugDataType.Ulong: return vals.Select(p => ulong.Parse(p)).ToArray();
- case DebugDataType.Float: return vals.Select(p => float.Parse(p)).ToArray();
- case DebugDataType.Double: return vals.Select(p => double.Parse(p)).ToArray();
- }
- }
- }
- }
- switch (type)
- {
- case DebugDataType.Bool: return bool.Parse(text);
- case DebugDataType.Byte: return byte.Parse(text);
- case DebugDataType.Short: return short.Parse(text);
- case DebugDataType.Ushort: return ushort.Parse(text);
- case DebugDataType.Int: return int.Parse(text);
- case DebugDataType.Uint: return uint.Parse(text);
- case DebugDataType.Long: return long.Parse(text);
- case DebugDataType.Ulong: return ulong.Parse(text);
- case DebugDataType.Float: return float.Parse(text);
- case DebugDataType.Double: return double.Parse(text);
- default: return text;
- }
- }
- }
- }
|