Files
XplorePlane/XP.Common/PdfViewer/Views/PdfViewerWindow.xaml.cs
T

133 lines
5.2 KiB
C#

using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using Telerik.Windows.Documents.Fixed.FormatProviders.Pdf;
using XP.Common.PdfViewer.Exceptions;
using XP.Common.PdfViewer.ViewModels;
namespace XP.Common.PdfViewer.Views
{
/// <summary>
/// PDF 阅读器窗口 code-behind | PDF viewer window code-behind
/// 负责在 Loaded 事件中加载 PDF 文档,在 Closed 事件中释放资源
/// Responsible for loading PDF document on Loaded event and releasing resources on Closed event
/// </summary>
public partial class PdfViewerWindow : Window
{
// 防止缩略图选择和页面跳转之间的循环触发 | Prevent circular trigger between thumbnail selection and page navigation
private bool _isSyncingSelection;
public PdfViewerWindow()
{
InitializeComponent();
Loaded += OnLoaded;
Closed += OnClosed;
}
/// <summary>
/// 窗口加载事件:通过 PdfFormatProvider 加载 PDF 文档到 RadPdfViewer
/// Window loaded event: load PDF document into RadPdfViewer via PdfFormatProvider
/// </summary>
private void OnLoaded(object sender, RoutedEventArgs e)
{
var vm = DataContext as PdfViewerWindowViewModel;
if (vm == null) return;
try
{
var provider = new PdfFormatProvider();
if (vm.PdfStream != null)
{
// 从文件流加载 PDF | Load PDF from stream
pdfViewer.Document = provider.Import(vm.PdfStream);
}
else if (!string.IsNullOrEmpty(vm.FilePath))
{
// 从文件路径加载 PDF | Load PDF from file path
using var stream = File.OpenRead(vm.FilePath);
pdfViewer.Document = provider.Import(stream);
}
// 文档加载后,监听页面变化以同步缩略图选中状态 | After document loaded, listen for page changes to sync thumbnail selection
pdfViewer.CurrentPageChanged += PdfViewer_CurrentPageChanged;
// 初始选中第一页缩略图 | Initially select first page thumbnail
if (thumbnailListBox.Items.Count > 0)
{
thumbnailListBox.SelectedIndex = 0;
}
}
catch (Exception ex) when (ex is not PdfLoadException)
{
// 捕获加载异常并包装为 PdfLoadException | Catch loading exceptions and wrap as PdfLoadException
throw new PdfLoadException(
"PDF 文件加载失败 | PDF file load failed",
vm.FilePath,
ex);
}
}
/// <summary>
/// 缩略图列表选择变化:跳转到对应页面 | Thumbnail selection changed: navigate to corresponding page
/// ListBox.SelectedIndex 从 0 开始,RadPdfViewer.CurrentPageNumber 从 1 开始
/// ListBox.SelectedIndex is 0-based, RadPdfViewer.CurrentPageNumber is 1-based
/// </summary>
private void ThumbnailListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (_isSyncingSelection) return;
if (thumbnailListBox.SelectedIndex < 0) return;
_isSyncingSelection = true;
try
{
// SelectedIndex(0-based) + 1 = CurrentPageNumber(1-based)
pdfViewer.CurrentPageNumber = thumbnailListBox.SelectedIndex + 1;
}
finally
{
_isSyncingSelection = false;
}
}
/// <summary>
/// PDF 阅读器页面变化:同步缩略图选中状态 | PDF viewer page changed: sync thumbnail selection
/// </summary>
private void PdfViewer_CurrentPageChanged(object? sender, EventArgs e)
{
if (_isSyncingSelection) return;
_isSyncingSelection = true;
try
{
// CurrentPageNumber(1-based) - 1 = SelectedIndex(0-based)
var index = pdfViewer.CurrentPageNumber - 1;
if (index >= 0 && index < thumbnailListBox.Items.Count)
{
thumbnailListBox.SelectedIndex = index;
thumbnailListBox.ScrollIntoView(thumbnailListBox.SelectedItem);
}
}
finally
{
_isSyncingSelection = false;
}
}
/// <summary>
/// 窗口关闭事件:释放 RadPdfViewer 文档资源
/// Window closed event: release RadPdfViewer document resources
/// </summary>
private void OnClosed(object? sender, EventArgs e)
{
// 取消事件订阅 | Unsubscribe events
pdfViewer.CurrentPageChanged -= PdfViewer_CurrentPageChanged;
// RadPdfViewer 内部管理文档资源,设置 Document = null 触发释放
// RadPdfViewer internally manages document resources, setting Document = null triggers release
pdfViewer.Document = null;
}
}
}