using System; using System.Windows; using Serilog.Events; using XP.Common.Logging.ViewModels; namespace XP.Common.GeneralForm.Views { /// /// 实时日志查看器窗口,订阅 Serilog 事件并实时显示 /// Real-time log viewer window, subscribes to Serilog events and displays in real-time /// public partial class RealTimeLogViewer : Window { private readonly RealTimeLogViewerViewModel _viewModel; /// /// 构造函数 | Constructor /// /// 最大行数限制,默认 2000 | Max line count, default 2000 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; } /// /// 接收 Serilog 日志事件 | Receive Serilog log event /// private void OnLogEventReceived(LogEvent logEvent) { _viewModel.AddLogEvent(logEvent); } /// /// 自动滚动到底部 | Auto-scroll to bottom /// 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 } } /// /// 窗口关闭时取消订阅,防止内存泄漏 | Unsubscribe on close to prevent memory leaks /// private void OnWindowClosed(object? sender, EventArgs e) { _viewModel.ScrollToBottomRequested -= OnScrollToBottomRequested; RealTimeLogSink.Instance.LogEventReceived -= OnLogEventReceived; } } }