方小清 發表於 2025-12-29 09:40:09

在C# WPF项目中集成PDF查看器的两种方法

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>方法1:通过 NuGet 包安装并手动创建控件(推荐)</li><ul class="second_class_ul"><li>1. 安装 NuGet 包</li><li>2. 在 XAML 中设置 WindowsFormsHost</li><li>3. 在代码后台创建和使用 PdfViewer</li></ul><li>方法2:创建自定义 WPF 控件(更优雅)</li><ul class="second_class_ul"><li>1. 创建 PdfViewerWrapper 用户控件</li><li>2. 在主窗口中使用自定义控件</li></ul><li>方法3:使用 PdfRenderer 而不是 PdfViewer</li><ul class="second_class_ul"></ul><li>解决常见问题</li><ul class="second_class_ul"><li>问题1:找不到 PdfiumViewer 控件</li><li>问题2:运行时异常(DLL 未找到)</li><li>问题3:设计时看不到控件</li></ul><li>完整示例项目结构</li><ul class="second_class_ul"></ul><li>在工具箱中手动添加控件(可选)</li><ul class="second_class_ul"></ul><li>总结</li><ul class="second_class_ul"></ul></ul></div><p class="maodian"></p><h2>方法1:通过 NuGet 包安装并手动创建控件(推荐)</h2>
<p class="maodian"></p><h3>1. 安装 NuGet 包</h3>
<div class="jb51code"><pre class="brush:xml;">&lt;!-- 在你的 WPF 项目的 .csproj 文件中添加 --&gt;
&lt;PackageReference Include="PdfiumViewer" Version="2.11.0" /&gt;
&lt;PackageReference Include="PdfiumViewer.Native.x86_64.v8-xfa" Version="2023.6.12.1" /&gt;
</pre></div>
<p>或通过 NuGet 包管理器控制台:</p>
<div class="jb51code"><pre class="brush:bash;">Install-Package PdfiumViewer
Install-Package PdfiumViewer.Native.x86_64.v8-xfa
</pre></div>
<p class="maodian"></p><h3>2. 在 XAML 中设置 WindowsFormsHost</h3>
<p>由于 PdfiumViewer 是 WinForms 控件,需要在 WPF 中使用 <code>WindowsFormsHost</code>:</p>
<div class="jb51code"><pre class="brush:xml;">&lt;!-- 在 MainWindow.xaml 中 --&gt;
&lt;Window x:Class="YourNamespace.MainWindow"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
      mc:Ignorable="d"
      Title="PDF Viewer" Height="600" Width="800"&gt;
   
    &lt;Grid&gt;
      &lt;WindowsFormsHost x:Name="pdfHost" Margin="10"/&gt;
    &lt;/Grid&gt;
&lt;/Window&gt;
</pre></div>
<p class="maodian"></p><h3>3. 在代码后台创建和使用 PdfViewer</h3>
<div class="jb51code"><pre class="brush:csharp;">using System;
using System.Windows;
using PdfiumViewer;
using System.Windows.Forms.Integration;

namespace YourNamespace
{
    public partial class MainWindow : Window
    {
      private PdfViewer pdfViewer;
      
      public MainWindow()
      {
            InitializeComponent();
            InitializePdfViewer();
      }
      
      private void InitializePdfViewer()
      {
            // 创建 PdfViewer 实例
            pdfViewer = new PdfViewer();
            pdfViewer.Dock = System.Windows.Forms.DockStyle.Fill;
            
            // 将 PdfViewer 添加到 WindowsFormsHost
            pdfHost.Child = pdfViewer;
      }
      
      // 打开 PDF 文件
      private void OpenPdf(string filePath)
      {
            try
            {
                // 加载 PDF 文档
                pdfViewer.Document = PdfDocument.Load(filePath);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"打开 PDF 失败: {ex.Message}");
            }
      }
      
      // 示例:在窗口加载时打开 PDF
      private void Window_Loaded(object sender, RoutedEventArgs e)
      {
            OpenPdf(@"C:\path\to\your\document.pdf");
      }
    }
}
</pre></div>
<p class="maodian"></p><h2>方法2:创建自定义 WPF 控件(更优雅)</h2>
<p class="maodian"></p><h3>1. 创建 PdfViewerWrapper 用户控件</h3>
<div class="jb51code"><pre class="brush:xml;">&lt;!-- PdfViewerWrapper.xaml --&gt;
&lt;UserControl x:Class="YourNamespace.Controls.PdfViewerWrapper"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             d:DesignHeight="450" d:DesignWidth="800"&gt;
    &lt;Grid&gt;
      &lt;WindowsFormsHost x:Name="host"/&gt;
    &lt;/Grid&gt;
&lt;/UserControl&gt;
</pre></div>
<div class="jb51code"><pre class="brush:csharp;">// PdfViewerWrapper.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
using PdfiumViewer;
using System.Windows.Forms.Integration;

namespace YourNamespace.Controls
{
    public partial class PdfViewerWrapper : UserControl
    {
      private PdfViewer pdfViewer;
      
      public PdfViewerWrapper()
      {
            InitializeComponent();
            InitializePdfViewer();
      }
      
      private void InitializePdfViewer()
      {
            pdfViewer = new PdfViewer
            {
                Dock = System.Windows.Forms.DockStyle.Fill
            };
            host.Child = pdfViewer;
      }
      
      // 打开 PDF 文件
      public void LoadPdf(string filePath)
      {
            try
            {
                pdfViewer.Document = PdfDocument.Load(filePath);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载 PDF 失败: {ex.Message}");
            }
      }
      
      // 从字节数组加载
      public void LoadPdf(byte[] pdfData)
      {
            try
            {
                pdfViewer.Document = PdfDocument.Load(pdfData);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载 PDF 失败: {ex.Message}");
            }
      }
      
      // 从流加载
      public void LoadPdf(System.IO.Stream stream)
      {
            try
            {
                pdfViewer.Document = PdfDocument.Load(stream);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载 PDF 失败: {ex.Message}");
            }
      }
      
      // 获取当前页面索引
      public int GetCurrentPage()
      {
            return pdfViewer?.Renderer?.Page ?? 0;
      }
      
      // 跳转到指定页面
      public void GoToPage(int page)
      {
            if (pdfViewer?.Renderer != null &amp;&amp; page &gt;= 0 &amp;&amp; page &lt; pdfViewer.Document.PageCount)
            {
                pdfViewer.Renderer.Page = page;
            }
      }
    }
}
</pre></div>
<p class="maodian"></p><h3>2. 在主窗口中使用自定义控件</h3>
<div class="jb51code"><pre class="brush:xml;">&lt;!-- MainWindow.xaml --&gt;
&lt;Window x:Class="YourNamespace.MainWindow"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:controls="clr-namespace:YourNamespace.Controls"
      Title="PDF Viewer" Height="600" Width="800"&gt;
   
    &lt;Grid&gt;
      &lt;Grid.RowDefinitions&gt;
            &lt;RowDefinition Height="Auto"/&gt;
            &lt;RowDefinition Height="*"/&gt;
      &lt;/Grid.RowDefinitions&gt;
      
      &lt;!-- 工具栏 --&gt;
      &lt;StackPanel Grid.Row="0" Orientation="Horizontal" Margin="10"&gt;
            &lt;Button Content="打开 PDF" Click="OpenPdfButton_Click" Margin="5"/&gt;
            &lt;Button Content="上一页" Click="PrevPageButton_Click" Margin="5"/&gt;
            &lt;Button Content="下一页" Click="NextPageButton_Click" Margin="5"/&gt;
            &lt;TextBlock Text="页码:" VerticalAlignment="Center" Margin="10,0,5,0"/&gt;
            &lt;TextBlock x:Name="pageInfo" VerticalAlignment="Center"/&gt;
      &lt;/StackPanel&gt;
      
      &lt;!-- PDF 查看器 --&gt;
      &lt;controls:PdfViewerWrapper x:Name="pdfViewerControl" Grid.Row="1"/&gt;
    &lt;/Grid&gt;
&lt;/Window&gt;
</pre></div>
<div class="jb51code"><pre class="brush:csharp;">// MainWindow.xaml.cs
using Microsoft.Win32;
using System.Windows;

namespace YourNamespace
{
    public partial class MainWindow : Window
    {
      public MainWindow()
      {
            InitializeComponent();
      }
      
      private void OpenPdfButton_Click(object sender, RoutedEventArgs e)
      {
            var openFileDialog = new OpenFileDialog
            {
                Filter = "PDF 文件|*.pdf|所有文件|*.*",
                Title = "选择 PDF 文件"
            };
            
            if (openFileDialog.ShowDialog() == true)
            {
                pdfViewerControl.LoadPdf(openFileDialog.FileName);
            }
      }
      
      private void PrevPageButton_Click(object sender, RoutedEventArgs e)
      {
            int currentPage = pdfViewerControl.GetCurrentPage();
            if (currentPage &gt; 0)
            {
                pdfViewerControl.GoToPage(currentPage - 1);
            }
      }
      
      private void NextPageButton_Click(object sender, RoutedEventArgs e)
      {
            int currentPage = pdfViewerControl.GetCurrentPage();
            pdfViewerControl.GoToPage(currentPage + 1);
      }
    }
}
</pre></div>
<p class="maodian"></p><h2>方法3:使用 PdfRenderer 而不是 PdfViewer</h2>
<p>如果你只需要简单的 PDF 渲染(没有工具栏),可以使用 <code>PdfRenderer</code>:</p>
<div class="jb51code"><pre class="brush:csharp;">using System.Windows;
using System.Windows.Forms.Integration;
using PdfiumViewer;

public partial class MainWindow : Window
{
    private PdfRenderer pdfRenderer;
   
    public MainWindow()
    {
      InitializeComponent();
      InitializePdfRenderer();
    }
   
    private void InitializePdfRenderer()
    {
      pdfRenderer = new PdfRenderer();
      pdfRenderer.Dock = System.Windows.Forms.DockStyle.Fill;
      pdfRenderer.ZoomMode = PdfViewerZoomMode.FitWidth;
      
      // 添加到 WindowsFormsHost
      var host = new WindowsFormsHost();
      host.Child = pdfRenderer;
      
      // 添加到 WPF 容器
      contentContainer.Children.Add(host);
    }
   
    private void LoadPdf(string filePath)
    {
      var document = PdfDocument.Load(filePath);
      pdfRenderer.Load(document);
    }
}
</pre></div>
<p class="maodian"></p><h2>解决常见问题</h2>
<p class="maodian"></p><h3>问题1:找不到 PdfiumViewer 控件</h3>
<ul><li><strong>原因</strong>:PdfiumViewer 是 WinForms 控件,不会自动出现在 WPF 工具箱中</li><li><strong>解决方案</strong>:手动创建控件实例,如上所示</li></ul>
<p class="maodian"></p><h3>问题2:运行时异常(DLL 未找到)</h3>
<div class="jb51code"><pre class="brush:xml;">&lt;!-- 在 .csproj 中确保包含 Native 包 --&gt;
&lt;PackageReference Include="PdfiumViewer.Native.x86_64.v8-xfa" Version="2023.6.12.1" /&gt;
&lt;!-- 或 x86 版本 --&gt;
&lt;PackageReference Include="PdfiumViewer.Native.x86.v8-xfa" Version="2023.6.12.1" /&gt;
</pre></div>
<p class="maodian"></p><h3>问题3:设计时看不到控件</h3>
<ul><li><strong>原因</strong>:WinForms 控件在 WPF 设计器中不可见</li><li><strong>解决方案</strong>:在设计时显示占位符,运行时加载真实控件</li></ul>
<div class="jb51code"><pre class="brush:xml;">&lt;!-- 在设计时显示标签,运行时替换 --&gt;
&lt;UserControl&gt;
    &lt;Grid&gt;
      &lt;TextBlock x:Name="designText"
                   Text="PDF Viewer (设计时)"
                   Visibility="{Binding IsInDesignMode, Converter={StaticResource BoolToVisibilityConverter}}"/&gt;
      &lt;WindowsFormsHost x:Name="host"
                        Visibility="{Binding IsInDesignMode, Converter={StaticResource BoolToVisibilityInverseConverter}}"/&gt;
    &lt;/Grid&gt;
&lt;/UserControl&gt;
</pre></div>
<p class="maodian"></p><h2>完整示例项目结构</h2>
<div class="jb51code"><pre class="brush:plain;">YourSolution/
├── YourWpfProject/
│   ├── Controls/
│   │   ├── PdfViewerWrapper.xaml
│   │   └── PdfViewerWrapper.xaml.cs
│   ├── MainWindow.xaml
│   ├── MainWindow.xaml.cs
│   └── YourWpfProject.csproj
└── YourWpfProject.sln
</pre></div>
<p class="maodian"></p><h2>在工具箱中手动添加控件(可选)</h2>
<p>虽然不能直接拖拽,但你可以:</p>
<ol><li><strong>创建自定义控件库</strong>:将 PdfViewerWrapper 控件编译为独立的 DLL</li><li><strong>添加到工具箱</strong>:<ul><li>右键点击工具箱 &rarr; &ldquo;选择项&rdquo;</li><li>浏览并选择你的控件 DLL</li><li>控件将出现在工具箱中</li></ul></li></ol>
<p class="maodian"></p><h2>总结</h2>
<p>在 WPF 中使用 PdfiumViewer 的关键步骤:</p>
<ol><li><strong>安装 NuGet 包</strong>:PdfiumViewer 及其 Native 包</li><li><strong>使用 WindowsFormsHost</strong>:承载 WinForms 控件</li><li><strong>代码创建控件</strong>:在代码后台或自定义用户控件中实例化 PdfViewer</li><li><strong>加载 PDF</strong>:使用 <code>PdfDocument.Load()</code> 方法</li></ol>
<p>虽然不能像 WinForms 那样直接在工具箱中拖拽,但通过创建自定义用户控件,你可以在 WPF 中获得类似的开发体验。</p>
<p>以上就是在C# WPF项目中集成PDF查看器的两种方法的详细内容,更多关于C# WPF集成PDF查看器的资料请关注琼殿技术社区其它相关文章!</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>C#&nbsp;WPF实现读取文件夹中的PDF并显示其页数的操作指南</li><li>基于C#和PDFSharp实现高效图片转PDF工具</li><li>使用C#实现将RTF转换为PDF</li><li>使用C#代码在PDF文档添加页码的操作指南</li><li>如何在C#中自动化生成PDF表格</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: 在C# WPF项目中集成PDF查看器的两种方法