当前位置: 代码网 > it编程>编程语言>Asp.net > 在C# WPF项目中集成PDF查看器的两种方法

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

2025年12月29日 Asp.net 我要评论
方法1:通过 nuget 包安装并手动创建控件(推荐)1. 安装 nuget 包<!-- 在你的 wpf 项目的 .csproj 文件中添加 --><packagereference

方法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

在工具箱中手动添加控件(可选)

虽然不能直接拖拽,但你可以:

  1. 创建自定义控件库:将 pdfviewerwrapper 控件编译为独立的 dll
  2. 添加到工具箱
    • 右键点击工具箱 → “选择项”
    • 浏览并选择你的控件 dll
    • 控件将出现在工具箱中

总结

在 wpf 中使用 pdfiumviewer 的关键步骤:

  1. 安装 nuget 包:pdfiumviewer 及其 native 包
  2. 使用 windowsformshost:承载 winforms 控件
  3. 代码创建控件:在代码后台或自定义用户控件中实例化 pdfviewer
  4. 加载 pdf:使用 pdfdocument.load() 方法

虽然不能像 winforms 那样直接在工具箱中拖拽,但通过创建自定义用户控件,你可以在 wpf 中获得类似的开发体验。

以上就是在c# wpf项目中集成pdf查看器的两种方法的详细内容,更多关于c# wpf集成pdf查看器的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com