作者:沐汐 Vicky
出处:http://www.cnblogs.com/EasyInvoice
一、 问题描述
在页面使用PictureBox 加载资料图片后,点击“打印”,只能打印图片首页,较大图片则无法全部打印。
二、 原因分析
PictureBox中打印图片时没有设置继续打印相关属性,因此每次只能打印第1页。
三、解决方法
PictureBox控件增加打印全部页面属性,如果为True,表示打印全部页面;如果为False,保留原有逻辑不变。
在打印全部页面时,将控件的图片按页面大小切割,打印页面索引小于页面总数时,设置打印属性PrintPageEventArgs. HasMorePages = true继续打印,打印完成后将该属性设置为False结束打印。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 | 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 } } |
以上就是c# winform 解决PictureBox 无法打印全部图片的问题的详细内容,更多关于解决picturebox无法打印图片的问题的资料请关注自学编程网其它相关文章!
- 本文固定链接: https://zxbcw.cn/post/202140/
- 转载请注明:必须在正文中标注并保留原文链接
- QQ群: PHP高手阵营官方总群(344148542)
- QQ群: Yii2.0开发(304864863)