将Feature/XP.Common和Feature/XP.Hardware分支合并至Develop/XP.forHardwareAndCommon,完善XPapp注册和相关硬件类库通用类库功能。
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using XP.Common.Localization;
|
||||
using XP.Common.Logging.Interfaces;
|
||||
using XP.Common.PdfViewer.Exceptions;
|
||||
using XP.Common.PdfViewer.Interfaces;
|
||||
using XP.Common.PdfViewer.ViewModels;
|
||||
using XP.Common.PdfViewer.Views;
|
||||
|
||||
namespace XP.Common.PdfViewer.Implementations
|
||||
{
|
||||
/// <summary>
|
||||
/// PDF 查看服务实现 | PDF viewer service implementation
|
||||
/// 基于 Telerik RadPdfViewer 实现 | Based on Telerik RadPdfViewer
|
||||
/// </summary>
|
||||
public class PdfViewerService : IPdfViewerService
|
||||
{
|
||||
private readonly ILoggerService _logger;
|
||||
private readonly IPdfPrintService _printService;
|
||||
private bool _disposed;
|
||||
|
||||
public PdfViewerService(ILoggerService logger, IPdfPrintService printService)
|
||||
{
|
||||
_logger = logger?.ForModule<PdfViewerService>()
|
||||
?? throw new ArgumentNullException(nameof(logger));
|
||||
_printService = printService
|
||||
?? throw new ArgumentNullException(nameof(printService));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过文件路径打开 PDF 阅读器窗口 | Open PDF viewer window by file path
|
||||
/// </summary>
|
||||
/// <param name="filePath">PDF 文件路径 | PDF file path</param>
|
||||
/// <exception cref="FileNotFoundException">文件不存在 | File not found</exception>
|
||||
/// <exception cref="PdfLoadException">PDF 格式无效 | Invalid PDF format</exception>
|
||||
public void OpenViewer(string filePath)
|
||||
{
|
||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||
|
||||
// 1. 验证文件路径存在 | Validate file path exists
|
||||
if (string.IsNullOrWhiteSpace(filePath))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(filePath),
|
||||
"文件路径不能为空 | File path cannot be null or empty");
|
||||
}
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
_logger.Error(new FileNotFoundException(filePath),
|
||||
"文件不存在 | File not found: {FilePath}", filePath);
|
||||
throw new FileNotFoundException(
|
||||
$"文件不存在 | File not found: {filePath}", filePath);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 2. 创建 PdfViewerWindowViewModel | Create PdfViewerWindowViewModel
|
||||
var viewModel = new PdfViewerWindowViewModel(filePath, _printService, _logger);
|
||||
|
||||
// 3. 创建 PdfViewerWindow 并设置 DataContext | Create PdfViewerWindow and set DataContext
|
||||
var window = new PdfViewerWindow
|
||||
{
|
||||
DataContext = viewModel
|
||||
};
|
||||
|
||||
// 4. 记录 Info 日志 | Log info
|
||||
_logger.Info("打开 PDF 阅读器窗口 | Opening PDF viewer window: {FileName}",
|
||||
Path.GetFileName(filePath));
|
||||
|
||||
// 5. 显示窗口(非模态)| Show window (non-modal)
|
||||
window.Show();
|
||||
}
|
||||
catch (Exception ex) when (ex is not FileNotFoundException
|
||||
and not ArgumentNullException
|
||||
and not PdfLoadException)
|
||||
{
|
||||
_logger.Error(ex, "PDF 文件加载失败 | PDF file load failed: {FilePath}", filePath);
|
||||
throw new PdfLoadException(
|
||||
"PDF 文件加载失败 | PDF file load failed", filePath, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过文件流打开 PDF 阅读器窗口 | Open PDF viewer window by stream
|
||||
/// </summary>
|
||||
/// <param name="stream">PDF 文件流 | PDF file stream</param>
|
||||
/// <param name="title">窗口标题(可选)| Window title (optional)</param>
|
||||
/// <exception cref="ArgumentNullException">流为 null | Stream is null</exception>
|
||||
/// <exception cref="PdfLoadException">PDF 格式无效 | Invalid PDF format</exception>
|
||||
public void OpenViewer(Stream stream, string? title = null)
|
||||
{
|
||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||
|
||||
// 1. 验证 stream 非 null | Validate stream is not null
|
||||
ArgumentNullException.ThrowIfNull(stream, nameof(stream));
|
||||
|
||||
try
|
||||
{
|
||||
// 2. 创建 ViewModel | Create ViewModel
|
||||
var viewModel = new PdfViewerWindowViewModel(stream, title, _printService, _logger);
|
||||
|
||||
// 3. 创建 PdfViewerWindow 并设置 DataContext | Create PdfViewerWindow and set DataContext
|
||||
var window = new PdfViewerWindow
|
||||
{
|
||||
DataContext = viewModel
|
||||
};
|
||||
|
||||
// 4. 记录 Info 日志 | Log info
|
||||
var displayTitle = title ?? LocalizationHelper.Get("PdfViewer_Title");
|
||||
_logger.Info("打开 PDF 阅读器窗口(流模式)| Opening PDF viewer window (stream mode): {Title}",
|
||||
displayTitle);
|
||||
|
||||
// 5. 显示窗口(非模态)| Show window (non-modal)
|
||||
window.Show();
|
||||
}
|
||||
catch (Exception ex) when (ex is not ArgumentNullException
|
||||
and not PdfLoadException)
|
||||
{
|
||||
_logger.Error(ex, "PDF 文件加载失败(流模式)| PDF file load failed (stream mode)");
|
||||
throw new PdfLoadException(
|
||||
"PDF 文件加载失败 | PDF file load failed", null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable 模式 | IDisposable Pattern
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源 | Dispose resources
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源的核心方法 | Core dispose method
|
||||
/// </summary>
|
||||
/// <param name="disposing">是否由 Dispose() 调用 | Whether called by Dispose()</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
// 释放托管资源 | Dispose managed resources
|
||||
_logger.Info("PdfViewerService 已释放 | PdfViewerService disposed");
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 终结器安全网 | Finalizer safety net
|
||||
/// 确保未显式释放时仍能清理非托管资源 | Ensures unmanaged resources are cleaned up if not explicitly disposed
|
||||
/// </summary>
|
||||
~PdfViewerService()
|
||||
{
|
||||
Dispose(disposing: false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user