C# 对PdfiumViewer工具栏进行自定义,实现放大缩小,首页, 尾页,上一页等功能。

news2024/9/22 13:36:40

文章目录

      • 前言
      • PdfiumViewer工具栏扩展
        • 1 创建winform工程,UI界面
        • 2 打印预览
        • 3 放大功能
        • 4 缩小功能
        • 5 按比例缩放
        • 6 全屏
        • 7 首页和尾页
        • 8 上一页和下一页
        • 9 页码输入框
        • 10 显示当前预览的页码
      • 小结

前言

关于PdfiumViewer的介绍 C# 使用PdfiumViewer实现对PDF文档打印预览(二),可以查看上一篇的文章。因为PdfiumViewer控件在工具栏展现的功能只有 保存、打印、放大、缩小这四个,现在想加上首页、尾页、上一页(下一页)的功能,以及显示当前页码,扩展一下功能。
在这里插入图片描述
改造成下面这个样子。
在这里插入图片描述

PdfiumViewer工具栏扩展

1 创建winform工程,UI界面

创建一个winform工程,在窗体上先放一个ToolStrip,再放置一个PdfiumViewer命名为pdfViewer1,将Dock属性设置为Full。
ToolStrip中从左到右控件的名称和对应的功能如下表:

控件类型控件名称描述
ToolStripButtonbtnPrint打印预览
ToolStripButtonbtnZomIn放大
ToolStripComboBoxcbZoomRate缩放比例
ToolStripButtonbtnZomOut缩小
ToolStripButtonbtnFullScreen全屏
ToolStripButtonbtnFirstPage首页
ToolStripButtonbtnPreviePage上一页
ToolStripTextBoxtbSetPage页码输入框
ToolStripLabellbTotalPage显示页码
ToolStripButtonbtnNextPage下一页
ToolStripButtonbtnLastPage尾页
ToolStripButtonbtnClose关闭

在这里插入图片描述
一些全局变量

        //打开的PDF文档
        PdfDocument document;
      
        //当前页码
        int curPageNum = 1;
       
        //是否全屏
        bool IsFull = false;
        
        //默认打印机
       string DefaultPrinter = null;

2 打印预览

使用C#自带的接口PrintDialog来实现打印,将PdfiumViewer中的PDF转换成系统的Document 并传递给PrintDialog即可,还可以设置PrintDialog的一些属性,比如开始打印页,总的页数等。

        /// <summary>
        /// 打印预览
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnPrint_Click(object sender, EventArgs e)
        {
            //实例化一个打印预览窗口对象
            using (var form = new PrintDialog())
            using (var doc = document.CreatePrintDocument(PdfPrintMode.CutMargin))
            {//将PdfViwer的PDF的文档 转换为System的document
               
                form.AllowSomePages = true;  //启用"页"
                form.Document = doc;         //设置要显示打印的文档
                form.UseEXDialog = true;
                form.Document.PrinterSettings.FromPage = 1;  //设置起始打印的页码
                form.Document.PrinterSettings.ToPage = document.PageCount;  //总的页码
                if (DefaultPrinter != null)
                    form.Document.PrinterSettings.PrinterName = DefaultPrinter;

                if (form.ShowDialog(FindForm()) == DialogResult.OK)
                {//弹出打印预览的窗口
                    try
                    {
                        if (form.Document.PrinterSettings.FromPage <= document.PageCount)
                            form.Document.Print();
                    }
                    catch
                    {
                        // Ignore exceptions; the printer dialog should take care of this.
                    }
                }
            }
        }

3 放大功能

使用PdfiumViewer的Renderer进行渲染放大页面。

        /// <summary>
        /// 放大
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnZomIn_Click(object sender, EventArgs e)
        {
            pdfViewer1.Renderer.ZoomIn();

        }

4 缩小功能

使用PdfiumViewer的Renderer进行渲染缩小页面。

        /// <summary>
        /// 缩小
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnZomOut_Click(object sender, EventArgs e)
        {
            pdfViewer1.Renderer.ZoomOut();
        }

5 按比例缩放

设置PdfiumViewer的RendererZoom 的属性(缩放比例因子)。

         /// <summary>
        /// 比例缩放
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CbZoomRate_SelectedIndexChanged(object sender, EventArgs e)
        {// 0:25% 1:50%  2:75%  3:100%  4:150%  5:200%  6:Page Width 7:Whole page
           if(cbZoomRate.SelectedIndex ==0 )
            {
                pdfViewer1.Renderer.Zoom = 0.25;
            }
            else if (cbZoomRate.SelectedIndex == 1)
            {
                pdfViewer1.Renderer.Zoom = 0.50;
            }
            else if (cbZoomRate.SelectedIndex == 2)
            {
                pdfViewer1.Renderer.Zoom = 0.75;
            }
            else if (cbZoomRate.SelectedIndex == 3)
            {
                pdfViewer1.Renderer.Zoom = 1.00;
            }
            else if (cbZoomRate.SelectedIndex == 4)
            {
                pdfViewer1.Renderer.Zoom = 1.50;
            }
            else if (cbZoomRate.SelectedIndex == 5)
            {
                pdfViewer1.Renderer.Zoom = 2.00;
            }
            else if(cbZoomRate.SelectedIndex == 6)
            {//page width

                int page = pdfViewer1.Renderer.Page;
                pdfViewer1.ZoomMode = PdfViewerZoomMode.FitWidth;
                pdfViewer1.Renderer.Zoom = 1;
                pdfViewer1.Renderer.Page = page;
            }
            else if (cbZoomRate.SelectedIndex == 7)
            {//Whole page 
                int page = pdfViewer1.Renderer.Page;
                pdfViewer1.ZoomMode = PdfViewerZoomMode.FitHeight;
                pdfViewer1.Renderer.Zoom = 1;
                pdfViewer1.Renderer.Page = page;
            }
        }

订阅了缩放更改事件 pdfViewer1.Renderer.ZoomChanged += Renderer_ZoomChanged; 当使用放大或缩小功能时,更新缩放比例的文本显示。

        /// <summary>
        /// 缩放改变时,显示此时的缩放比例
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void Renderer_ZoomChanged(object sender, EventArgs e)
        {
            cbZoomRate.Text = (pdfViewer1.Renderer.Zoom * 100).ToString("f0") + "%";
        }

6 全屏

工具栏有全屏按钮,顺便可以加个鼠标右键菜单可以退出全屏的功能。

        /// <summary>
        /// 窗体最大化显示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnFullScreen_Click(object sender, EventArgs e)
        {
            IsFull = !IsFull;
                      
            if(IsFull)
            {//全屏

                //隐藏工具栏和状态栏
                this.toolStrip1.Visible = false;
                this.statusStrip1.Visible = false;
                //最大化窗体
                this.FormBorderStyle = FormBorderStyle.None;
                this.WindowState = FormWindowState.Maximized;
            }
            else
            {
                this.toolStrip1.Visible = true;
                this.statusStrip1.Visible = true;

                this.WindowState = FormWindowState.Normal;
                this.FormBorderStyle = FormBorderStyle.FixedDialog;
            }
        }

7 首页和尾页

更改Renderer渲染Page的索引为0,即是首页了。
首页

        /// <summary>
        /// 首页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnFirstPage_Click(object sender, EventArgs e)
        {
             //设置当前页码为1
            curPageNum = 1;
            //渲染页是0 下标从0开始
            pdfViewer1.Renderer.Page = curPageNum - 1;
        }

尾页

       /// <summary>
        /// 尾页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnLastPage_Click(object sender, EventArgs e)
        {
            curPageNum = document.PageCount;

            pdfViewer1.Renderer.Page = curPageNum - 1;

        }

8 上一页和下一页

更改Renderer渲染Page的索引
上一页

        /// <summary>
        /// 上一页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnPreviePage_Click(object sender, EventArgs e)
        {
            //curPageNum 是从1开始计数的,因为工具栏还有一个Label显示当前页的页码
            // 获取当前页页码
            curPageNum = pdfViewer1.Renderer.Page + 1;
            if (curPageNum -1 < 0 )
            {//已经是首页(第1页)了,则返回
                return;
            }
            //当前页减1
            curPageNum--;
            //渲染上一页
            pdfViewer1.Renderer.Page = curPageNum - 1;

        }

下一页

        /// <summary>
        /// 下一页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnNextPage_Click(object sender, EventArgs e)
        {
            //计算当前页
            curPageNum = pdfViewer1.Renderer.Page + 1;
            if (curPageNum    > document.PageCount)
            {//当前页已经是最后一页,则返回
                return;
            }
            //当前页+1,就是下一页
            curPageNum++;
            //因为curPageNum是从1开始计数,而Page下标是从0开始,所以还要减1
            pdfViewer1.Renderer.Page = curPageNum - 1;
        }

9 页码输入框

根据输入的页码,跳转显示PDF文档的页。

        /// <summary>
        /// 设置页码
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TbSetPage_KeyPress(object sender, KeyPressEventArgs e)
        {
            
            string text = tbSetPage.Text.Trim();
            int page = -1;
            //将文本强转为数值
           int.TryParse(text, out page);

            if(page < 0 || page > document.PageCount)
            {//数值超限
                return;
            }
            curPageNum = page;
            //设定跳转的页
            pdfViewer1.Renderer.Page = curPageNum - 1;
        }

10 显示当前预览的页码

订阅 pdfViewer1.Renderer.DisplayRectangleChanged += Renderer_DisplayRectangleChanged; 当显示预览的矩形框变化时,那么预览的页码也可能随之更改。上下翻页,还有设定页,也会触发该事件。

        /// <summary>
        /// 翻页矩形框变化时,更新当前页码
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void Renderer_DisplayRectangleChanged(object sender, EventArgs e)
        {
            tbSetPage.Text = (pdfViewer1.Renderer.Page + 1).ToString();
            lbCurrentPage.Text = (pdfViewer1.Renderer.Page + 1).ToString();
        }

小结

1 打印功能:使用自带的PrintDialog 对象(dlg),并将PdfiumViewer中的PdfDocument文档赋值给dlg就可以了。

2 缩放功能:主要是对PdfiumViewer中的组成之一的Renderer的Zoom属性进行设置。

3 换页功能:主要是对PdfiumViewer中的组成之一的Renderer的Page属性进行设置。

4 注意:开源的PdfiumViewer需要与pdfium.dll一起配合使用,放在软件同一目录下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/506196.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【论文学习】ECAPA-TDNN: Emphasized Channel Attention, Propagation and Aggregation

ECAPA-TDNN: Emphasized Channel Attention, Propagation and Aggregation 目录 ECAPA-TDNN: Emphasized Channel Attention, Propagation and Aggregation摘要1 介绍2 DNN说话人识别系统2.1 Extended-TDNN x-vector2.2 基于ResNet的r-vector 3 提出的ECAPA-TDNN架构3.1 依赖于…

【Unity之c#专题篇】—核心章题单实践

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

电脑开关机-第14届蓝桥杯省赛Scratch初级组真题第1题

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第130讲。 电脑开关机&#xff0c;本题是2023年5月7日举行的第14届蓝桥杯省赛Scratch图形化编程初级组真题第1题&#…

flstudio21有什么新功能,主题随心换,苹果M2/1家族芯片原生支持

FL Studio 21推出 – 新功能和改进。如果您从事音乐制作&#xff0c;那么您不可能没有听说过 FL Studio&#xff0c;或者很可能已经使用过这个音乐程序。好了&#xff0c;新版本的 FL Studio 21 DAW已经准备好向公众发布了。Image-line 正在为 2023 年的大型揭幕准备最终细节。…

go 源码解读 - sync.WaitGroup

go version 1.19.7 在 Go 语言中&#xff0c;sync.WaitGroup 是一个并发编程的同步工具&#xff0c;用于等待一组 Goroutine 执行完毕。 当需要等待多个 Goroutine 完成任务后才能执行下一步操作时&#xff0c;我们可以使用 sync.WaitGroup 实现协程间的同步。它提供了 Add()…

测试:概念篇

目录 简单介绍测试 我们先简单的介绍一下测试工程师 简单来看看测试和开发的区别 测试的基本概念 什么是需求 BUG 的概念 测试用例 什么是测试用例&#xff1f; 为什么有测试用例 测试周期 开发模型 瀑布模型&#xff1a; 螺旋模型&#xff1a; 敏捷软件开发 V …

PostgreSQL 查找重复数据(二)

创建表和测试数据&#xff1a; -- DROP TABLE IF EXISTS people; CREATE TABLE people (id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,name varchar(50) NOT NULL,email varchar(100) NOT NULL );INSERT INTO people(name, email) VALUES (张三, zhangsantest.com),(李…

操作系统考试复习-—第四章 分段式 段页式存储方式

分段从存储管理方式&#xff1a;一方面是通常的程序都可以分为若干段&#xff0c;另一方面是实现和满足信息共享&#xff0c;信息保护&#xff0c;动态链接以及信息的动态增长等需要。也都是以段为基本单位实现的。所以说&#xff0c;分段存储管理方式更符合用户和程序员多方面…

JWT认证

一、什么是JWT 官网地址: https://jwt.io/introduction/ jsonwebtoken&#xff08;JWT&#xff09;是一个开放标准&#xff08;rfc7519&#xff09;&#xff0c;它定义了一种紧凑的、自包含的方式&#xff0c;用于在各方之间以JSON对象安全地传输信息。此信息可以验证和信任&…

华为nqa实验拓扑案例

bqa是一种实时的网络性能探测和统计技术&#xff0c;可以对响应时间、网络抖动、丢包率等网络信息进行统计。如图1所示&#xff0c;接口备份与NQA联动功能配置相对简单&#xff0c;只需在本端RouterA上配置NQA测试例&#xff0c;并在RouterA的备份接口上配置接口备份与NQA联动&…

自定义组件中如何注入Spring底层的组件

1.概述 自定义的组件要想使用Spring容器底层的一些组件&#xff0c;比如ApplicationContext&#xff08;IOC容器&#xff09;、底层的BeanFactory等等&#xff0c;那么只需要让自定义组件实现XxxAware接口即可。此时&#xff0c;Spring在创建对象的时候&#xff0c;会调用XxxA…

搞懂 API,API 常见技术使用场景分享

API&#xff08;应用程序编程接口&#xff09;是一种允许软件应用程序之间相互交互和通信的技术。以下是API常用的使用场景&#xff1a; 应用程序开发 API通常被用于网站或应用程序的开发中&#xff0c;以便在不同平台、语言及数据库之间获取数据或进行消息传递。例如&#xff…

探索数字化转型新道路!流辰信息微服务与您一起创未来!

科技在进步&#xff0c;社会在发展&#xff0c;办公自动化也在高速发展中。数字化转型是当下企业获得长久发展的趋势之一&#xff0c;在信息瞬间万变的社会中&#xff0c;谁掌握了核心技术&#xff0c;谁能与时代同步&#xff0c;谁就能开启新的康庄大道&#xff0c;谁就能在转…

VS2017配置Qt——超详细步骤教学(看完不会算你狠)

一、环境要求 visual studio 2017 vsaddin Qt14.1 mysql 注意mysql环境与msvc2017编译器环境保持一致。 mysql32位 配 msvc2017 32位 或 mysql64位 配 msvc2017 64位 注意&#xff1a;环境不一致会导致软件运行错误&#xff0c;为了避免这些错误&#xff0c;要将…

第1章计算机系统漫游之 “源代码的编译与执行” 及 “操作系统管理硬件”

文章目录 1、信息就是位上下文2、程序被其他程序翻译成不同的格式3、了解编译系统如何工作的益处4、处理器读并解释储存在存储器中的指令4.1 系统的硬件组成4.2 执行 hello 程序 5、高速缓存6、形成层次结构的存储设备7、操作系统管理硬件7.1 进程7.2 线程7.3 虚拟存储器7.4 文…

docker容器内使用cat命令修改文件

有时候docker容器内部没装vi 或vim命令&#xff0c;无法使用vi来修改文件 可以使用cat命令来查看文件 cat 主要功能一次显示整个文件:cat filename 从键盘创建一个文件:cat > filename 只能创建新文件,不能编辑已有文件 将几个文件合并为一个文件:cat file1 file2 > fi…

最新黄金市场价格分析之干掉调整浪

等待的过程无疑是最令人心烦的。各位朋友应该试过&#xff0c;等待自己的朋友、亲人&#xff0c;等等结果&#xff0c;等待成绩公布等等。但是等待是我们干任何事都必不可少的过程&#xff0c;是我们缓冲、蓄力的阶段。最新黄金市场价格分析中的等待&#xff0c;体现在调整浪的…

Python心经(3)

这一节总结点demo和常用知识点 目录 有关字符串格式化打印的 lambda匿名函数&#xff0c;&#xff0c;将匿名函数作为参数传入 文件读写 生成器 python的装饰器 简单的网站代码&#xff1a; 有关三元运算 推导式&#xff1a; 新浪面试题&#xff1a; 有关面向对象里…

SpringBoot项目中一些常用的,工具类

推荐多使用这个&#xff1a; Hutool参考文档Hutool&#xff0c;Java工具集https://hutool.cn/docs/#/core/%E9%9B%86%E5%90%88%E7%B1%BB/%E9%9B%86%E5%90%88%E5%B7%A5%E5%85%B7-CollUtil?id%e4%bb%8b%e7%bb%8d 1&#xff1a;断言 断言是一个逻辑判断&#xff0c;用于检查不应…

芯片封装技术(三)

Interposer 是一种用于连接芯片的中间层技术&#xff0c;它的基底通常是一块硅基底&#xff0c;而硅基底也是 Substrate 的一种。因此&#xff0c;Interposer 与 Substrate 有一定的关系。对于RDL Interposer来说&#xff0c;Si Interposer的信号布线密度进一步提高&#xff0c…