c# winform 解決PictureBox 無法打印全部圖片的問題
作者:沐汐 Vicky
出處:http://www.cnblogs.com/EasyInvoice
一、 問題描述
在頁面使用PictureBox 加載資料圖片后,點擊“打印”,只能打印圖片首頁,較大圖片則無法全部打印。
二、 原因分析
PictureBox中打印圖片時沒有設(shè)置繼續(xù)打印相關(guān)屬性,因此每次只能打印第1頁。
三、解決方法
PictureBox控件增加打印全部頁面屬性,如果為True,表示打印全部頁面;如果為False,保留原有邏輯不變。
在打印全部頁面時,將控件的圖片按頁面大小切割,打印頁面索引小于頁面總數(shù)時,設(shè)置打印屬性PrintPageEventArgs. HasMorePages = true繼續(xù)打印,打印完成后將該屬性設(shè)置為False結(jié)束打印。

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;//處理狀態(tài)
private HScrollBar hScrollBar;//水平滾動條
private VScrollBar vScrollBar;//垂直滾動條
private PrintDocument printDocument;//打印對象
private Rectangle currRect;//現(xiàn)在矩形對象
private Bitmap currBmp;//現(xiàn)在圖形對象
//private int hScrollBarMidVal;//水平滾動條中間值
//private int vScrollBarMidVal;//垂直滾動條中間值
private RectangleF srcRect;
private RectangleF destRect;
private bool isMoveScrollBar;//是否移動滾動條
int currentPageIndex = 0;//當(dāng)前頁面
int pageCount = 0;//打印頁數(shù)
/// <summary>
/// 構(gòu)造函數(shù)
/// </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);
//構(gòu)造水平滾動條
hScrollBar = new HScrollBar();
hScrollBar.Visible = false;
hScrollBar.Dock = DockStyle.Bottom;
hScrollBar.Scroll += new ScrollEventHandler(scrollBar_Scroll);
this.Controls.Add(hScrollBar);
//構(gòu)造垂直滾動條
vScrollBar = new VScrollBar();
vScrollBar.Visible = false;
vScrollBar.Dock = DockStyle.Right;
vScrollBar.Scroll +=new ScrollEventHandler(scrollBar_Scroll);
this.Controls.Add(vScrollBar);
}
#region 公共屬性
[Category("外觀"), Description("獲取或設(shè)置圖片")]
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("獲取或設(shè)置圖片縮放比例")]
public Int32 ScaleSize
{
get { return scaleSize; }
set
{
if (value > 1 && value < 51)
{
scaleSize = value;
}
}
}
//縮放倍數(shù)
private int scaleScope = 5;
[Category("其它"), Description("獲取或設(shè)置圖片最大縮放倍數(shù)")]
public int ScaleScope
{
get { return scaleScope; }
set
{
if (value > 1 && value < 11)
{
scaleScope = value;
}
}
}
//圖片邊框顏色
//private Color borderColor = Color.DarkGray;
//[Category("其它"), Description("獲取或設(shè)置圖片邊框顏色")]
//public Color BorderColor
//{
// get { return borderColor; }
// set { borderColor = value; }
//}
//圖片邊框?qū)挾?
private int borderWidth = 5;
[Category("其它"), Description("獲取或設(shè)置圖片邊框?qū)挾?)]
public Int32 BorderWidth
{
get { return borderWidth; }
set { borderWidth = value; }
}
//打印全部頁面
[Category("其它"),Description("true-打印全部頁面,false-打印首頁")]
public bool PrintAllPages { get; set; }
#endregion
#region 內(nèi)部公共方法
/// <summary>
/// 從新繪制
/// </summary>
protected override void OnPaint(PaintEventArgs pe)
{
// TODO: 在此處添加自定義繪制代碼
// 調(diào)用基類 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;
//是否繪制到中心點坐標(biāo)
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>
/// 重寫控件大小發(fā)生改變事件
/// </summary>
protected override void OnClientSizeChanged(EventArgs e)
{
base.OnClientSizeChanged(e);
displayScrollBars();
setScrollBarsValues();
Invalidate();
}
#endregion
#region 圖片打印與預(yù)覽
/// <summary>
/// 打印圖片
/// </summary>
public void PrintPictrue()
{
PrintDialog printDialog = new PrintDialog();
printDialog.Document = printDocument;
//added by lky 2017-11-16 修復(fù)Windows 7 x64位環(huán)境無法彈出打印對話框的問題
printDialog.UseEXDialog = true;
if (printDialog.ShowDialog() == DialogResult.OK)
{
try
{
printDocument.Print();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "打印出錯", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
/// <summary>
/// 打印預(yù)覽
/// </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);//水平方向切割頁數(shù)
int verticalTimes = (int)Math.Ceiling((decimal)currBmp.Height / pageHeight);//垂直方向切割頁數(shù)
if (pageCount == 0)
{
pageCount = horizontalTimes * verticalTimes;//總頁數(shù)
currentPageIndex = 0;
}
int horizontalCurrentPosition = (currentPageIndex % horizontalTimes);//當(dāng)前打印的水平偏移頁數(shù)
int verticalCurrentPosition = (int)Math.Floor((decimal)currentPageIndex / horizontalTimes);//當(dāng)前打印的垂直偏移頁數(shù)
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;//是否繼續(xù)打印
if (!e.HasMorePages) pageCount = 0;//打印頁數(shù)置為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 圖片放大、縮小、原始大小、全屏顯示、旋轉(zhuǎn)功能
/// <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>
/// 旋轉(zhuǎn)圖片
/// </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>
/// 設(shè)置水平滾動條與垂直滾動條值
/// </summary>
private void setScrollBarsValues()
{
//設(shè)置水平滾動條值
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;
//繪制坐標(biāo)為中心點
if (this.SizeMode == PictureBoxSizeMode.CenterImage)
{
if (hScrollBar.Value == 0 || isMoveScrollBar == false)
{
hScrollBar.Value = (hScrollBar.Maximum - hScrollBar.LargeChange) / 2;
}
}
}
else
{ hScrollBar.Value = 0; }
//設(shè)置垂直滾動條值
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;
//繪制坐標(biāo)為中心點
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
}
}
以上就是c# winform 解決PictureBox 無法打印全部圖片的問題的詳細內(nèi)容,更多關(guān)于解決picturebox無法打印圖片的問題的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#基礎(chǔ)語法:結(jié)構(gòu)和類區(qū)別詳解
這篇文章主要介紹了C#基礎(chǔ)語法:結(jié)構(gòu)和類詳解,本文總結(jié)了一些結(jié)構(gòu)和類的不同之處并給出了測試區(qū)別特性代碼,需要的朋友可以參考下2015-06-06
C#實現(xiàn)任意數(shù)據(jù)類型轉(zhuǎn)成json格式輸出
C#實現(xiàn)任意數(shù)據(jù)類型轉(zhuǎn)成json格式輸出。需要的朋友可以過來參考下,希望對大家有所幫助2013-10-10

