c# – printDialog页面范围不适用于DataGridView

我已经搜索了EXTENSIVELY这个问题的解决方案,但是找不到任何可以用于我当前代码的东西.

我有一个表单应用程序,它对SQL Server表执行查询并使用行填充dataGridView.然后我有一个按钮将dataGridView打印到打印机.到目前为止,我已经使用printDialog嵌入了printPreviewDialog打印按钮的覆盖,并且我还获得了“打印页面范围”字段未被阻止,但是给出页面范围仍会打印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);
        }
    }

解决方法:

您坚持使用现有代码解决方案,从而设置了相当不灵活的限制.这是完全写的,没有考虑从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;
    }
}
上一篇:c# – 如何完全禁用DataGridView上的Tab键但是能否选择行?


下一篇:c# – 如何在1列datagridview中显示mysql数据库中的2个不同列