Files
XplorePlane/XP.Common/Logging/Views/RealTimeLogViewer.xaml.cs
T

86 lines
2.9 KiB
C#

using System;
using System.Windows;
using Serilog.Events;
using XP.Common.Logging.ViewModels;
namespace XP.Common.GeneralForm.Views
{
/// <summary>
/// 实时日志查看器窗口,订阅 Serilog 事件并实时显示
/// Real-time log viewer window, subscribes to Serilog events and displays in real-time
/// </summary>
public partial class RealTimeLogViewer : Window
{
private readonly RealTimeLogViewerViewModel _viewModel;
/// <summary>
/// 构造函数 | Constructor
/// </summary>
/// <param name="maxLines">最大行数限制,默认 2000 | Max line count, default 2000</param>
public RealTimeLogViewer(int maxLines = 2000)
{
_viewModel = new RealTimeLogViewerViewModel { MaxLines = maxLines };
DataContext = _viewModel;
InitializeComponent();
// 继承主窗口图标 | Inherit main window icon
if (Application.Current?.MainWindow != null)
{
Icon = Application.Current.MainWindow.Icon;
}
// 订阅自动滚动事件 | Subscribe to auto-scroll event
_viewModel.ScrollToBottomRequested += OnScrollToBottomRequested;
// 加载缓冲区中的历史日志 | Load buffered history logs
var history = RealTimeLogSink.Instance.GetBufferedHistory();
foreach (var logEvent in history)
{
_viewModel.AddLogEvent(logEvent);
}
// 订阅 Serilog Sink 事件(在历史加载之后,避免重复)| Subscribe after history load
RealTimeLogSink.Instance.LogEventReceived += OnLogEventReceived;
Closed += OnWindowClosed;
}
/// <summary>
/// 接收 Serilog 日志事件 | Receive Serilog log event
/// </summary>
private void OnLogEventReceived(LogEvent logEvent)
{
_viewModel.AddLogEvent(logEvent);
}
/// <summary>
/// 自动滚动到底部 | Auto-scroll to bottom
/// </summary>
private void OnScrollToBottomRequested()
{
try
{
if (LogGridView.Items.Count > 0)
{
var lastItem = LogGridView.Items[LogGridView.Items.Count - 1];
LogGridView.ScrollIntoView(lastItem);
}
}
catch
{
// 滚动失败时静默处理 | Silently handle scroll failures
}
}
/// <summary>
/// 窗口关闭时取消订阅,防止内存泄漏 | Unsubscribe on close to prevent memory leaks
/// </summary>
private void OnWindowClosed(object? sender, EventArgs e)
{
_viewModel.ScrollToBottomRequested -= OnScrollToBottomRequested;
RealTimeLogSink.Instance.LogEventReceived -= OnLogEventReceived;
}
}
}