zoukankan      html  css  js  c++  java
  • c# winform 解决PictureBox 无法打印全部图片的问题

    一、   问题描述

    在页面使用PictureBox 加载资料图片后,点击“打印”,只能打印图片首页,较大图片则无法全部打印。

    二、   原因分析

    PictureBox中打印图片时没有设置继续打印相关属性,因此每次只能打印第1页。

    三、解决方法

    PictureBox控件增加打印全部页面属性,如果为True,表示打印全部页面;如果为False,保留原有逻辑不变。

    在打印全部页面时,将控件的图片按页面大小切割,打印页面索引小于页面总数时,设置打印属性PrintPageEventArgs. HasMorePages = true继续打印,打印完成后将该属性设置为False结束打印。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Printing;
    using System.Text;
    using System.Windows.Forms;
    
    namespace MyClass
    {
    
        //public enum OperationState { Default, ZoomIn, ZoomOut };
    
        public partial class UCPictureBox : PictureBox
        {
            //private OperationState operationState;//处理状态
            private HScrollBar hScrollBar;//水平滚动条
            private VScrollBar vScrollBar;//垂直滚动条
            private PrintDocument printDocument;//打印对象
            private Rectangle currRect;//现在矩形对象
            private Bitmap currBmp;//现在图形对象
            //private int hScrollBarMidVal;//水平滚动条中间值
            //private int vScrollBarMidVal;//垂直滚动条中间值
            private RectangleF srcRect;
            private RectangleF destRect;
            private bool isMoveScrollBar;//是否移动滚动条        
            int currentPageIndex = 0;//当前页面
            int pageCount = 0;//打印页数
            
            /// <summary>
            /// 构造函数
            /// </summary>
            public UCPictureBox()
            {
                InitializeComponent();
                SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
                SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    
                //hScrollBarMidVal = 0;
                //vScrollBarMidVal = 0;            
                //operationState = OperationState.Default;
                isMoveScrollBar = false;
                srcRect = new RectangleF();
                destRect = new RectangleF();
                printDocument = new PrintDocument();
                printDocument.PrintPage += new PrintPageEventHandler(printDocument_PrintPage);
    
                //构造水平滚动条
                hScrollBar = new HScrollBar();
                hScrollBar.Visible = false;
                hScrollBar.Dock = DockStyle.Bottom;
                hScrollBar.Scroll += new ScrollEventHandler(scrollBar_Scroll);
                this.Controls.Add(hScrollBar);
    
                //构造垂直滚动条
                vScrollBar = new VScrollBar();
                vScrollBar.Visible = false;
                vScrollBar.Dock = DockStyle.Right;
                vScrollBar.Scroll +=new ScrollEventHandler(scrollBar_Scroll);
                this.Controls.Add(vScrollBar);
            }
    
            #region 公共属性
    
            [Category("外观"), Description("获取或设置图片")]
            public new Image Image
            {
                get { return base.Image; }
                set
                {
                    if (value != null)
                    {
                        base.Image = value;
                        currRect.Width = base.Image.Width;
                        currRect.Height = base.Image.Height;
                        hScrollBar.Value = 0;
                        vScrollBar.Value = 0;
                        displayScrollBars();
                        setScrollBarsValues();
                        Invalidate();
                    }
                }
            }
    
            //缩放比例
            private int scaleSize = 1;
            [Category("其它"), Description("获取或设置图片缩放比例")]
            public Int32 ScaleSize
            {
                get { return scaleSize; }
                set
                {
                    if (value > 1 && value < 51)
                    {
                        scaleSize = value;
                    }
                }
            }
    
            //缩放倍数
            private int scaleScope = 5;
            [Category("其它"), Description("获取或设置图片最大缩放倍数")]
            public int ScaleScope
            {
                get { return scaleScope; }
                set
                {
                    if (value > 1 && value < 11)
                    {
                        scaleScope = value;
                    }
                }
            }
    
            //图片边框颜色
            //private Color borderColor = Color.DarkGray;
            //[Category("其它"), Description("获取或设置图片边框颜色")]
            //public Color BorderColor
            //{
            //    get { return borderColor; }
            //    set { borderColor = value; }
            //}
    
            //图片边框宽度
            private int borderWidth = 5;
            [Category("其它"), Description("获取或设置图片边框宽度")]
            public Int32 BorderWidth
            {
                get { return borderWidth; }
                set { borderWidth = value; }
            }
    
            //打印全部页面
            [Category("其它"),Description("true-打印全部页面,false-打印首页")]
            public bool PrintAllPages { get; set; }
    
            #endregion
    
            #region 内部公共方法
    
            /// <summary>
            /// 从新绘制
            /// </summary>
            protected override void OnPaint(PaintEventArgs pe)
            {
                // TODO: 在此处添加自定义绘制代码
                // 调用基类 OnPaint
                base.OnPaint(pe);
    
                if (this.Image != null)
                {
                    if (currBmp != null) { currBmp.Dispose(); }
                    currBmp = new Bitmap(currRect.Width + 2 * borderWidth, currRect.Height + 2 * borderWidth);
                    //绘制新图片
                    using (Graphics g = Graphics.FromImage(currBmp))
                    {
                        using (Pen pen = new Pen(BackColor, borderWidth))
                        {
                            g.DrawRectangle(pen, borderWidth * 0.5f, borderWidth * 0.5f,
                                            currRect.Width + borderWidth,
                                            currRect.Height + borderWidth);
                        }
                        g.DrawImage(this.Image, borderWidth, borderWidth, currRect.Width, currRect.Height);
                    }
    
                    //图片绘制到控件上
                    pe.Graphics.Clear(BackColor);
                    if (hScrollBar.Visible || vScrollBar.Visible)
                    {//滚动条可见
                        drawDisplayedScrollBars(pe.Graphics);
                    }
                    else
                    {//滚动条不可见
                        float x = 0, y = 0;
                        isMoveScrollBar = false;
    
                        //是否绘制到中心点坐标
                        if (this.SizeMode == PictureBoxSizeMode.CenterImage)
                        {
                            x = Math.Abs(ClientSize.Width - currBmp.Width) * 0.5f;
                            y = Math.Abs(ClientSize.Height - currBmp.Height) * 0.5f;
                        }
                        pe.Graphics.DrawImage(currBmp, x, y, currBmp.Width, currBmp.Height);
                    }
                }
            }
    
            /// <summary>
            /// 重写控件大小发生改变事件
            /// </summary>
            protected override void OnClientSizeChanged(EventArgs e)
            {
                base.OnClientSizeChanged(e);
                displayScrollBars();
                setScrollBarsValues();
                Invalidate();
            }
    
            #endregion
    
            #region 图片打印与预览
    
            /// <summary>
            /// 打印图片
            /// </summary>
            public void PrintPictrue()
            {
                PrintDialog printDialog = new PrintDialog();
                printDialog.Document = printDocument;
                //added by lky 2017-11-16 修复Windows 7 x64位环境无法弹出打印对话框的问题
                printDialog.UseEXDialog = true;
                if (printDialog.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        printDocument.Print();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "打印出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }
            }
    
            /// <summary>
            /// 打印预览
            /// </summary>
            public void PrintPreview()
            {
                PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog();
                printPreviewDialog.Document = printDocument;
                try
                {
                    printPreviewDialog.ShowDialog();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "打印出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
    
            /// <summary>
            /// 打印图片事件
            /// </summary>
            private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
            {
                if (currBmp == null)
                    return;
                try
                {
                    if (PrintAllPages)//added by lky 2018-1-15 打印全部页面
                    {
                        int pageWith =(int) e.PageSettings.PrintableArea.Width;
                        int pageHeight = (int)e.PageSettings.PrintableArea.Height;
                        int horizontalTimes = (int)Math.Ceiling((decimal)currBmp.Width / pageWith);//水平方向切割页数
                        int verticalTimes = (int)Math.Ceiling((decimal)currBmp.Height / pageHeight);//垂直方向切割页数
                        if (pageCount == 0)
                        {
                            pageCount = horizontalTimes * verticalTimes;//总页数
                            currentPageIndex = 0;
                        }
                        int horizontalCurrentPosition = (currentPageIndex % horizontalTimes);//当前打印的水平偏移页数
                        int verticalCurrentPosition = (int)Math.Floor((decimal)currentPageIndex / horizontalTimes);//当前打印的垂直偏移页数
                        int x = horizontalCurrentPosition * pageWith;//水平方向打印偏移位置
                        int y = verticalCurrentPosition * pageHeight;//垂直方向打印偏移位置
                        int leftX = (currBmp.Width - x) > 0 ? (currBmp.Width - x) : 0;//水平方向未打印尺寸
                        int leftY = (currBmp.Height - y) > 0 ? (currBmp.Height - y) : 0;//垂直方向未打印尺寸
    
                        Bitmap printBmp = (Bitmap)currBmp.Clone(new Rectangle(x, y, (leftX > pageWith ? pageWith : leftX),
                            (leftY > pageHeight ? pageHeight : leftY)), currBmp.PixelFormat); //待打印图片缓存
                        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                        e.Graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
    
                        e.Graphics.DrawImage(printBmp, 0, 0, printBmp.Width, printBmp.Height);
                        printBmp.Dispose();
                        currentPageIndex++;
                        e.HasMorePages = currentPageIndex < pageCount;//是否继续打印
                        if (!e.HasMorePages) pageCount = 0;//打印页数置为0
                    }
                    else //仅打印首页
                    {
                        Bitmap printBmp = (Bitmap)currBmp.Clone(); 
                        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                        e.Graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
                        e.Graphics.DrawImage(printBmp, 0, 0, printBmp.Width, printBmp.Height);
                        printBmp.Dispose();
                    }
                }
                catch (Exception ex)
                {
                    //写日志文件
                    LogWriter.Write(LOG_CATEGORY.WIN_UI, LOG_LEVEL.ERROR, "UCPicturBox.PrintPage" + ex.ToString());
                }
            }
    
            #endregion
    
            #region 图片放大、缩小、原始大小、全屏显示、旋转功能
    
            /// <summary>
            /// 放大图片
            /// </summary>
            public void ZoomInPicture()
            {
                if (this.Image != null)
                {
                    //operationState = OperationState.ZoomIn;
                    double scale = 1 + (scaleSize * 0.01);
                    currRect.Width = Convert.ToInt32(currRect.Width * scale);
                    currRect.Height = currRect.Width * this.Image.Height / this.Image.Width;
                    if (currRect.Width < (this.Image.Width * scaleScope))
                    {                    
                        displayScrollBars();
                        setScrollBarsValues();
                        Invalidate();
                    }
                }
            }
    
            /// <summary>
            /// 缩小图片
            /// </summary>
            public void ZoomOutPicture()
            {
                if (this.Image != null)
                {
                    //operationState = OperationState.ZoomOut;
                    double scale = 1 - (scaleSize * 0.01);
                    currRect.Width = Convert.ToInt32(currRect.Width * scale);
                    currRect.Height = currRect.Width * this.Image.Height / this.Image.Width;
                    displayScrollBars();
                    setScrollBarsValues();
                    Invalidate();
                }
            }
    
            /// <summary>
            /// 原始大小
            /// </summary>
            public void ZoomOriginalPicture()
            {
                if (this.Image != null)
                {
                    //operationState = OperationState.Default;
                    isMoveScrollBar = false;
                    currRect.Width = this.Image.Width;
                    currRect.Height = this.Image.Height;
                    displayScrollBars();
                    setScrollBarsValues();
                    Invalidate();
                }
            }
    
            /// <summary>
            /// 全屏显示
            /// </summary>
            public void ZoomShowAllPicture()
            {
                if (this.Image != null)
                {
                    if (this.Image.Width > this.Image.Height)
                    {
                        currRect.Width = ClientSize.Width - 2 * borderWidth;
                        currRect.Height = currRect.Width * this.Image.Height / this.Image.Width;
                        if ((currRect.Height + 2 * borderWidth) > ClientSize.Height)
                        {
                            currRect.Height = ClientSize.Height - 2 * borderWidth;
                            currRect.Width = currRect.Height * this.Image.Width / this.Image.Height;
                        }
                        //if ((currRect.Height + 2 * borderWidth) > ClientSize.Height)
                        //{
                        //    currRect.Width = ClientSize.Width - 2 * borderWidth - vScrollBar.Width;
                        //    currRect.Height = currRect.Width * this.Image.Height / this.Image.Width;
                        //}
                    }
                    else
                    {
                        currRect.Height = ClientSize.Height - 2 * borderWidth;
                        currRect.Width = currRect.Height * this.Image.Width / this.Image.Height;
                        if ((currRect.Width + 2 * borderWidth) > ClientSize.Width)
                        {
                            currRect.Width = ClientSize.Width - 2 * borderWidth;
                            currRect.Height = currRect.Width * this.Image.Width / this.Image.Height;
                        }
                        //if ((currRect.Width + 2 * borderWidth) > ClientSize.Width)
                        //{
                        //    hScrollBar.Value = 0;
                        //    currRect.Height = ClientSize.Height - 2 * borderWidth - hScrollBar.Height;
                        //    currRect.Width = currRect.Height * this.Image.Width / this.Image.Height;
                        //}
                    }
                    isMoveScrollBar = false;
                    displayScrollBars();
                    setScrollBarsValues();
                    Invalidate();
                }
            }
    
            /// <summary>
            /// 旋转图片
            /// </summary>
            public void RotatePicture()
            {
                if (this.Image != null)
                {
                    isMoveScrollBar = false;
                    this.Image.RotateFlip(RotateFlipType.Rotate90FlipNone);
                    int tempWidth = currRect.Width;
                    currRect.Width = currRect.Height;
                    currRect.Height = tempWidth;
                    displayScrollBars();
                    setScrollBarsValues();
                    Invalidate();
                }
            }
    
            /// <summary>
            /// 显示水平滚动条与垂直滚动条
            /// </summary>
            private void displayScrollBars()
            {
                //是否显示水平滚动条
                if ((currRect.Width + 2 * borderWidth) > ClientSize.Width)
                { hScrollBar.Visible = true; }
                else
                { hScrollBar.Visible = false; }
    
                //是否显示垂直滚动条
                if ((currRect.Height + 2 * borderWidth) > ClientSize.Height)
                { vScrollBar.Visible = true; }
                else
                { vScrollBar.Visible = false; }
            }
    
            /// <summary>
            /// 设置水平滚动条与垂直滚动条值
            /// </summary>
            private void setScrollBarsValues()
            {
                //设置水平滚动条值
                if (hScrollBar.Visible)
                {
                    hScrollBar.Minimum = 0;
                    hScrollBar.Maximum = currRect.Width - ClientSize.Width + 2 * borderWidth;
                    hScrollBar.LargeChange = currRect.Width / 10;
                    if (vScrollBar.Visible)
                    {
                        hScrollBar.Maximum += vScrollBar.Width;
                    }
                    if (hScrollBar.LargeChange > hScrollBar.Maximum)
                    {
                        hScrollBar.LargeChange = hScrollBar.Maximum - 1;
                    }
                    hScrollBar.SmallChange = hScrollBar.LargeChange / 5;
                    hScrollBar.Maximum += hScrollBar.LargeChange;
    
                    //绘制坐标为中心点
                    if (this.SizeMode == PictureBoxSizeMode.CenterImage)
                    {
                        if (hScrollBar.Value == 0 || isMoveScrollBar == false)
                        {
                            hScrollBar.Value = (hScrollBar.Maximum - hScrollBar.LargeChange) / 2;
                        }
                    }
                }
                else
                { hScrollBar.Value = 0; }
    
                //设置垂直滚动条值
                if (vScrollBar.Visible)
                {
                    vScrollBar.Minimum = 0;
                    vScrollBar.Maximum = currRect.Height - ClientSize.Height + 2 * borderWidth;
                    vScrollBar.LargeChange = currRect.Height / 10;
                    if (hScrollBar.Visible)
                    {
                        vScrollBar.Maximum += hScrollBar.Height;
                    }
                    if (vScrollBar.LargeChange > vScrollBar.Maximum)
                    {
                        vScrollBar.LargeChange = vScrollBar.Maximum - 1;
                    }
                    vScrollBar.SmallChange = vScrollBar.LargeChange / 5;
                    vScrollBar.Maximum += vScrollBar.LargeChange;
    
                    //绘制坐标为中心点
                    if (this.SizeMode == PictureBoxSizeMode.CenterImage)
                    {
                        if (vScrollBar.Value == 0 || isMoveScrollBar ==false)
                        {                        
                            vScrollBar.Value = (vScrollBar.Maximum - vScrollBar.LargeChange) / 2;
                        }
                    }
                }
                else
                { vScrollBar.Value = 0; }
            }
    
            /// <summary>
            /// 移动水平滚动条事件
            /// </summary>
            private void scrollBar_Scroll(object sender, ScrollEventArgs e)
            {
                isMoveScrollBar = true;
                using (Graphics graphics = this.CreateGraphics())
                {
                    drawDisplayedScrollBars(graphics);
                }
                this.Update();
            }
    
            /// <summary>
            /// 从新绘制显示的滚动条
            /// </summary>
            private void drawDisplayedScrollBars(Graphics graphics)
            {
                float x = 0, y = 0;
    
                if (this.SizeMode == PictureBoxSizeMode.CenterImage)
                {
                    x = Math.Abs(ClientSize.Width - currBmp.Width - vScrollBar.Width) * 0.5f;
                    y = Math.Abs(ClientSize.Height - currBmp.Height - hScrollBar.Height) * 0.5f;
                }
                if (hScrollBar.Visible == false)
                {//水平滚动条不可见
                    destRect.X = x;
                    destRect.Y = 0;
                    srcRect.X = 0;
                    srcRect.Y = vScrollBar.Value;
                }
                else if (vScrollBar.Visible == false)
                {//垂直滚动条不可见
                    destRect.X = 0;
                    destRect.Y = y;
                    srcRect.Y = 0;
                    srcRect.X = hScrollBar.Value;
                }
                else
                {//两个滚动条都可见
                    destRect.X = 0;
                    destRect.Y = 0;
                    srcRect.X = hScrollBar.Value;
                    srcRect.Y = vScrollBar.Value;
                }
                destRect.Width = currBmp.Width;
                destRect.Height = currBmp.Height;
                srcRect.Width = currBmp.Width;
                srcRect.Height = currBmp.Height;
                graphics.DrawImage(currBmp, destRect, srcRect, GraphicsUnit.Pixel);
            }
    
            #endregion
        }
    }
    

      

  • 相关阅读:
    019_Mac实用的图像备份工具
    016_把普通用户免秘钥加入root用户的几种方式
    027_磁盘维护命令du等
    026_lsof命令经验总结
    004_wireshark专题
    029_mount bind挂载
    023_nginx跨域问题
    mysql-5.7 group commit 详解
    二段式提交协议
    mysql-5.7 密码过期详解
  • 原文地址:https://www.cnblogs.com/EasyInvoice/p/8333923.html
Copyright © 2011-2022 走看看