printDialog 页面范围不适用于 DataGridView

Chr*_*uce 5 c# printing datagridview winforms

我已经广泛搜索了这个问题的解决方案,但没有找到任何可以与我当前的代码一起使用的东西。

我有一个表单应用程序,它对 SQL Server 表执行查询并dataGridView用行填充 a 。然后我有一个按钮可以打印dataGridView到打印机。我已经printPreviewDialog使用 a嵌入了打印按钮的覆盖printDialog,并且我还解除了“打印页面范围”字段的阻塞,但是给出一个页面范围仍然会打印dataGridView. 例如,如果我dataGridView要打印 20 页,并且我选择了范围内的第 2-4 页,我仍然会得到所有 20 页。

我已经看到了一些示例,DocumentPaginator但我没有使用直接从 打印的文档dataGridView,此时我被卡住了。

以下是我用于打印dataGridView.

private void printActivityReportToolStripMenuItem_Click(object sender, EventArgs e)
        {



     PrintPreviewDialog objPPdialog = new PrintPreviewDialog();
     objPPdialog.Document = printDocument1;

     ToolStrip ts = new ToolStrip();
     ts.Name = "wrongToolStrip";
     foreach (Control ctl in objPPdialog.Controls)
     {
         if (ctl.Name.Equals("toolStrip1"))
         {
             ts = ctl as ToolStrip;
             break;
         }
     }
     ToolStripButton printButton = new ToolStripButton();
     foreach (ToolStripItem tsi in ts.Items)
     {
         if (tsi.Name.Equals("printToolStripButton"))
         {
             printButton = tsi as ToolStripButton;
         }
     }

     printButton.Click += new EventHandler(this.SelectPrinterAfterPreview);

     ts.Items.Remove(printButton);
     ToolStripButton b = new ToolStripButton();
     b.ImageIndex = printButton.ImageIndex;
     b.Visible = true;
     ts.Items.Insert(0, b);
     b.Click += new EventHandler(this.SelectPrinterAfterPreview);

     printDocument1.DefaultPageSettings.Landscape = true;
     //((ToolStripButton)((ToolStrip)objPPdialog.Controls[1]).Items[0]).
     objPPdialog.ShowDialog();

    }

    private void SelectPrinterAfterPreview(object sender, EventArgs e)
    {
        PrintDialog printDialog = new PrintDialog();
        printDialog.Document = printDocument1;
        printDocument1.DefaultPageSettings.Landscape = true;

        printDialog.AllowSomePages = true;
        printDialog.UseEXDialog = true;
        if (DialogResult.OK == printDialog.ShowDialog())
        {
            printDocument1.DocumentName = "Activity Report";
            printDocument1.Print();
        }
    }

    private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
    {


        try
        {
            strFormat = new StringFormat();
            strFormat.Alignment = StringAlignment.Near;
            strFormat.LineAlignment = StringAlignment.Center;
            strFormat.Trimming = StringTrimming.EllipsisCharacter;

            arrColumnLefts.Clear();
            arrColumnWidths.Clear();
            iCellHeight = 0;
            iRow = 0;
            bFirstPage = true;
            bNewPage = true;

            // Calculating Total Widths
            iTotalWidth = 0;
            foreach (DataGridViewColumn dgvGridCol in dataGridView1.Columns)
            {
                iTotalWidth += dgvGridCol.Width;
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

    private void printDocument1_PrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
    {
        try
        {
            //Set the left margin
            int iLeftMargin = e.MarginBounds.Left;
            //Set the top margin
            int iTopMargin = e.MarginBounds.Top;
            //Whether more pages have to print or not
            bool bMorePagesToPrint = false;
            int iTmpWidth = 0;

            //For the first page to print set the cell width and header height
            if (bFirstPage)
            {
                foreach (DataGridViewColumn GridCol in dataGridView1.Columns)
                {
                    iTmpWidth = (int)(Math.Floor((double)((double)GridCol.Width /
                        (double)iTotalWidth * (double)iTotalWidth *
                        ((double)e.MarginBounds.Width / (double)iTotalWidth))));

                    iHeaderHeight = (int)(e.Graphics.MeasureString(GridCol.HeaderText,
                        GridCol.InheritedStyle.Font, iTmpWidth).Height) + 11;

                    // Save width and height of headers
                    arrColumnLefts.Add(iLeftMargin);
                    arrColumnWidths.Add(iTmpWidth);
                    iLeftMargin += iTmpWidth;
                }
            }
            //Loop till all the grid rows not get printed
            while (iRow <= dataGridView1.Rows.Count - 1)
            {
                DataGridViewRow GridRow = dataGridView1.Rows[iRow];
                //Set the cell height
                iCellHeight = GridRow.Height;
                int iCount = 0;
                //Check whether the current page settings allows more rows to print
                if (iTopMargin + iCellHeight >= e.MarginBounds.Height + e.MarginBounds.Top)
                {
                    bNewPage = true;
                    bFirstPage = false;
                    bMorePagesToPrint = true;
                    break;
                }
                else
                {
                    if (bNewPage)
                    {
                        //Draw Header
                        e.Graphics.DrawString("Activity Report for "+txtBoxUsername.Text+"",
                            new Font(dataGridView1.Font, FontStyle.Bold),
                            Brushes.Black, e.MarginBounds.Left,
                            e.MarginBounds.Top - e.Graphics.MeasureString("Activity Report for " + txtBoxUsername.Text + "",
                            new Font(dataGridView1.Font, FontStyle.Bold),
                            e.MarginBounds.Width).Height - 13);

                        String strDate = DateTime.Now.ToLongDateString() + " " +
                            DateTime.Now.ToShortTimeString();
                        //Draw Date
                        e.Graphics.DrawString(strDate,
                            new Font(dataGridView1.Font, FontStyle.Bold), Brushes.Black,
                            e.MarginBounds.Left +
                            (e.MarginBounds.Width - e.Graphics.MeasureString(strDate,
                            new Font(dataGridView1.Font, FontStyle.Bold),
                            e.MarginBounds.Width).Width),
                            e.MarginBounds.Top - e.Graphics.MeasureString("Activity Report for " + txtBoxUsername.Text + "",
                            new Font(new Font(dataGridView1.Font, FontStyle.Bold),
                            FontStyle.Bold), e.MarginBounds.Width).Height - 13);

                        //Draw Columns                 
                        iTopMargin = e.MarginBounds.Top;
                        foreach (DataGridViewColumn GridCol in dataGridView1.Columns)
                        {
                            e.Graphics.FillRectangle(new SolidBrush(Color.LightGray),
                                new Rectangle((int)arrColumnLefts[iCount], iTopMargin,
                                (int)arrColumnWidths[iCount], iHeaderHeight));

                            e.Graphics.DrawRectangle(Pens.Black,
                                new Rectangle((int)arrColumnLefts[iCount], iTopMargin,
                                (int)arrColumnWidths[iCount], iHeaderHeight));

                            e.Graphics.DrawString(GridCol.HeaderText,
                                GridCol.InheritedStyle.Font,
                                new SolidBrush(GridCol.InheritedStyle.ForeColor),
                                new RectangleF((int)arrColumnLefts[iCount], iTopMargin,
                                (int)arrColumnWidths[iCount], iHeaderHeight), strFormat);
                            iCount++;
                        }
                        bNewPage = false;
                        iTopMargin += iHeaderHeight;
                    }
                    iCount = 0;
                    //Draw Columns Contents                
                    foreach (DataGridViewCell Cel in GridRow.Cells)
                    {
                        if (Cel.Value != null)
                        {
                            Font font = new Font("Arial", 7);
                            e.Graphics.DrawString(Cel.Value.ToString(),font,new SolidBrush(Cel.InheritedStyle.ForeColor),new RectangleF((int)arrColumnLefts[iCount],(float)iTopMargin,(int)arrColumnWidths[iCount], (float)iCellHeight),strFormat);
                        }
                        //Drawing Cells Borders 
                        e.Graphics.DrawRectangle(Pens.Black,
                            new Rectangle((int)arrColumnLefts[iCount], iTopMargin,
                            (int)arrColumnWidths[iCount], iCellHeight));
                        iCount++;
                    }
                }
                iRow++;
                iTopMargin += iCellHeight;
            }
            //If more lines exist, print another page.
            if (bMorePagesToPrint)
                e.HasMorePages = true;
            else
                e.HasMorePages = false;
        }
        catch (Exception exc)
        {
            MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK,
               MessageBoxIcon.Error);
        }
    }
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 4

您坚持要求解决方案适用于您现有的代码,从而设置了相当不灵活的限制。这完全是在没有考虑从 1 以外的页面开始的情况下编写的。实际上修复起来并不难,您只需根据起始页码找出从数据网格中的哪一行开始即可。

但你所要求的是可能的。您可以通过创建一个新的 PrintDocument 来欺骗现有代码,该新 PrintDocument 只是伪造您要跳过的页面的打印设备上下文。它不会比实际打印它们更清楚。将新类添加到您的项目中并粘贴下面所示的代码。建造。从工具箱顶部删除新组件,替换现有的 PrintDocument。根据 PrintDialog.PrinterSettings.PageFrom/To 属性值,在代码中设置 PageFrom 和 PageTo 属性。

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Printing;
using System.Drawing.Imaging;

class PagedPrintDocument : PrintDocument {
    public int PageFrom { get; set; }
    public int PageTo { get; set; }
    public int Page { get; private set; }

    protected override void OnBeginPrint(PrintEventArgs e) {
        Page = 0;
        if (PageTo < PageFrom) e.Cancel = true;
        base.OnBeginPrint(e);
    }

    protected override void OnPrintPage(PrintPageEventArgs e) {
        while (++Page < PageFrom) {
            // Fake the pages that need to be skipped by printing them to a Metafile
            IntPtr hDev = e.Graphics.GetHdc();
            try {
                using (var mf = new Metafile(hDev, e.PageBounds))
                using (var gr = Graphics.FromImage(mf)) {
                    var ppe = new PrintPageEventArgs(gr, e.MarginBounds, e.PageBounds, e.PageSettings);
                    base.OnPrintPage(ppe);
                }
            }
            finally {
                e.Graphics.ReleaseHdc(hDev);
            }

        }

        // Print the real page
        base.OnPrintPage(e);

        // No need to continue past PageTo
        if (PageTo > 0 && Page >= PageTo) e.HasMorePages = false;
    }
}
Run Code Online (Sandbox Code Playgroud)