106 lines
3.5 KiB
C#
106 lines
3.5 KiB
C#
|
|
using System.Windows;
|
|||
|
|
using System.Windows.Controls;
|
|||
|
|
|
|||
|
|
namespace SHH.CameraDashboard.Controls
|
|||
|
|
{
|
|||
|
|
public partial class DiagnosticControl : UserControl
|
|||
|
|
{
|
|||
|
|
public event EventHandler RequestCollapse;
|
|||
|
|
private ApiLogEntry _selectedItem;
|
|||
|
|
private bool _isInitialized = false;
|
|||
|
|
|
|||
|
|
public DiagnosticControl()
|
|||
|
|
{
|
|||
|
|
InitializeComponent();
|
|||
|
|
_isInitialized = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 外部(MainWindow或BottomDock)调用此方法推送日志
|
|||
|
|
public void PushLog(ApiLogEntry entry)
|
|||
|
|
{
|
|||
|
|
this.Dispatcher.Invoke(() => {
|
|||
|
|
// 确保 XAML 中的 ListView 名称是 LogList
|
|||
|
|
LogList.Items.Insert(0, entry);
|
|||
|
|
|
|||
|
|
// 限制日志数量,防止内存溢出(可选)
|
|||
|
|
if (LogList.Items.Count > 100) LogList.Items.RemoveAt(100);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void Close_Click(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
RequestCollapse?.Invoke(this, EventArgs.Empty);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void LogList_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|||
|
|
{
|
|||
|
|
if (!_isInitialized) return;
|
|||
|
|
_selectedItem = LogList.SelectedItem as ApiLogEntry;
|
|||
|
|
UpdateDetailView();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void Tab_Checked(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
if (!_isInitialized) return;
|
|||
|
|
UpdateDetailView();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void UpdateDetailView()
|
|||
|
|
{
|
|||
|
|
// 防御性编程:检查所有可能为 null 的 UI 元素
|
|||
|
|
if (TxtEmpty == null || TxtContent == null || BtnReq == null) return;
|
|||
|
|
|
|||
|
|
if (_selectedItem == null)
|
|||
|
|
{
|
|||
|
|
TxtEmpty.Visibility = Visibility.Visible;
|
|||
|
|
TxtContent.Visibility = Visibility.Collapsed; // 隐藏编辑框更美观
|
|||
|
|
TxtContent.Text = string.Empty;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
TxtEmpty.Visibility = Visibility.Collapsed;
|
|||
|
|
TxtContent.Visibility = Visibility.Visible;
|
|||
|
|
|
|||
|
|
// 根据切换按钮显示对应内容
|
|||
|
|
TxtContent.Text = (BtnReq.IsChecked == true)
|
|||
|
|
? _selectedItem.RequestBody
|
|||
|
|
: _selectedItem.ResponseBody;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void Clear_Click(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
// 具体的清空逻辑
|
|||
|
|
LogList.Items.Clear();
|
|||
|
|
_selectedItem = null;
|
|||
|
|
UpdateDetailView();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void Copy_Click(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
// 如果没选中或内容本身为空,不执行复制
|
|||
|
|
if (_selectedItem == null || TxtContent == null || string.IsNullOrEmpty(TxtContent.Text)) return;
|
|||
|
|
|
|||
|
|
// 使用之前定义的带重试机制的 Helper
|
|||
|
|
ClipboardHelper.SetText(TxtContent.Text);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 右键菜单复制逻辑
|
|||
|
|
private void CopySummary_Click(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
if (LogList.SelectedItem is ApiLogEntry item)
|
|||
|
|
ClipboardHelper.SetText($"[{item.Time}] {item.Url} - {item.StatusCode}");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void CopyRequest_Click(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
if (LogList.SelectedItem is ApiLogEntry item)
|
|||
|
|
ClipboardHelper.SetText(item.RequestBody ?? "");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void CopyResponse_Click(object sender, RoutedEventArgs e)
|
|||
|
|
{
|
|||
|
|
if (LogList.SelectedItem is ApiLogEntry item)
|
|||
|
|
ClipboardHelper.SetText(item.ResponseBody ?? "");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|