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
{
///
/// 默认通讯调试页:按设备类型自适应——PLC 设备(PlcCommunicationBase)显示寄存器读写(带数据类型/长度),
/// 其余(串口/文本)显示收发;底部收发/读写日志(双击清空)。
/// 未在 [Communication] 特性指定 DebugPageType 的设备均用本页。直接操作 BindCommunication 得到的实例。
///
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