方法1:通过 nuget 包安装并手动创建控件(推荐)
1. 安装 nuget 包
<!-- 在你的 wpf 项目的 .csproj 文件中添加 --> <packagereference include="pdfiumviewer" version="2.11.0" /> <packagereference include="pdfiumviewer.native.x86_64.v8-xfa" version="2023.6.12.1" />
或通过 nuget 包管理器控制台:
install-package pdfiumviewer install-package pdfiumviewer.native.x86_64.v8-xfa
2. 在 xaml 中设置 windowsformshost
由于 pdfiumviewer 是 winforms 控件,需要在 wpf 中使用 windowsformshost:
<!-- 在 mainwindow.xaml 中 -->
<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">
<grid>
<windowsformshost x:name="pdfhost" margin="10"/>
</grid>
</window>
3. 在代码后台创建和使用 pdfviewer
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");
}
}
}
方法2:创建自定义 wpf 控件(更优雅)
1. 创建 pdfviewerwrapper 用户控件
<!-- pdfviewerwrapper.xaml -->
<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">
<grid>
<windowsformshost x:name="host"/>
</grid>
</usercontrol>
// 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 && page >= 0 && page < pdfviewer.document.pagecount)
{
pdfviewer.renderer.page = page;
}
}
}
}
2. 在主窗口中使用自定义控件
<!-- mainwindow.xaml -->
<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">
<grid>
<grid.rowdefinitions>
<rowdefinition height="auto"/>
<rowdefinition height="*"/>
</grid.rowdefinitions>
<!-- 工具栏 -->
<stackpanel grid.row="0" orientation="horizontal" margin="10">
<button content="打开 pdf" click="openpdfbutton_click" margin="5"/>
<button content="上一页" click="prevpagebutton_click" margin="5"/>
<button content="下一页" click="nextpagebutton_click" margin="5"/>
<textblock text="页码:" verticalalignment="center" margin="10,0,5,0"/>
<textblock x:name="pageinfo" verticalalignment="center"/>
</stackpanel>
<!-- pdf 查看器 -->
<controls:pdfviewerwrapper x:name="pdfviewercontrol" grid.row="1"/>
</grid>
</window>
// 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 > 0)
{
pdfviewercontrol.gotopage(currentpage - 1);
}
}
private void nextpagebutton_click(object sender, routedeventargs e)
{
int currentpage = pdfviewercontrol.getcurrentpage();
pdfviewercontrol.gotopage(currentpage + 1);
}
}
}
方法3:使用 pdfrenderer 而不是 pdfviewer
如果你只需要简单的 pdf 渲染(没有工具栏),可以使用 pdfrenderer:
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);
}
}
解决常见问题
问题1:找不到 pdfiumviewer 控件
- 原因:pdfiumviewer 是 winforms 控件,不会自动出现在 wpf 工具箱中
- 解决方案:手动创建控件实例,如上所示
问题2:运行时异常(dll 未找到)
<!-- 在 .csproj 中确保包含 native 包 --> <packagereference include="pdfiumviewer.native.x86_64.v8-xfa" version="2023.6.12.1" /> <!-- 或 x86 版本 --> <packagereference include="pdfiumviewer.native.x86.v8-xfa" version="2023.6.12.1" />
问题3:设计时看不到控件
- 原因:winforms 控件在 wpf 设计器中不可见
- 解决方案:在设计时显示占位符,运行时加载真实控件
<!-- 在设计时显示标签,运行时替换 -->
<usercontrol>
<grid>
<textblock x:name="designtext"
text="pdf viewer (设计时)"
visibility="{binding isindesignmode, converter={staticresource booltovisibilityconverter}}"/>
<windowsformshost x:name="host"
visibility="{binding isindesignmode, converter={staticresource booltovisibilityinverseconverter}}"/>
</grid>
</usercontrol>
完整示例项目结构
yoursolution/ ├── yourwpfproject/ │ ├── controls/ │ │ ├── pdfviewerwrapper.xaml │ │ └── pdfviewerwrapper.xaml.cs │ ├── mainwindow.xaml │ ├── mainwindow.xaml.cs │ └── yourwpfproject.csproj └── yourwpfproject.sln
在工具箱中手动添加控件(可选)
虽然不能直接拖拽,但你可以:
- 创建自定义控件库:将 pdfviewerwrapper 控件编译为独立的 dll
- 添加到工具箱:
- 右键点击工具箱 → “选择项”
- 浏览并选择你的控件 dll
- 控件将出现在工具箱中
总结
在 wpf 中使用 pdfiumviewer 的关键步骤:
- 安装 nuget 包:pdfiumviewer 及其 native 包
- 使用 windowsformshost:承载 winforms 控件
- 代码创建控件:在代码后台或自定义用户控件中实例化 pdfviewer
- 加载 pdf:使用
pdfdocument.load()方法
虽然不能像 winforms 那样直接在工具箱中拖拽,但通过创建自定义用户控件,你可以在 wpf 中获得类似的开发体验。
以上就是在c# wpf项目中集成pdf查看器的两种方法的详细内容,更多关于c# wpf集成pdf查看器的资料请关注代码网其它相关文章!
发表评论