如何调整e.Graphics绘制的区域(视口)?

时间:2014-06-11 19:49:34

标签: c# printing gdi+ componentone c1flexgrid

我正在使用PrintDocument.Print()来启动打印过程,我在其中打印数据网格(C1FlexGrid)和一些页眉和页脚信息。这是一个有点复杂的印刷过程。我使用的是标准的PrintDocument方法,但由于我想要点击页面,我可以控制所发生的一切。

我遇到的问题是我想缩小绘制网格控件的区域。当我绘制页眉和页脚时,我正在计算它们将消耗的空间,以及网格占用的空间。网格控件有自己的PrintDocumentGridRenderer类,它提供PrintPage()方法,我调用它来渲染PrintDocument的Graphics对象上的网格。

我无法弄清楚如何限制网格可以适应的区域,但在之后我已经绘制了页眉/页脚并知道剩下的空间是什么。

这里有一些代码,严重剥离了我认为的本质:

private void PrintDocument_PrintPage(Object sender, PrintPageEventArgs e)
{
    //I tried putting a non-drawing version of DrawHeadersAndFooters() here to get the calculated space and then reset the Margin...but it's always one call behind the Graphics object, meaning that it has no effect on the first page.  In fact, because Setup() gets called with two different margins at that point, the pages end up very badly drawn.

    _gridRenderer.Setup(e);  //this is the PrintDocumentGridRender object and Setup() figures out page layout (breaks and such)

    DrawHeadersAndFooters(e.Graphics, e.MarginBounds);
    Int32 newX = _printProperties.GridBounds.X - e.MarginBounds.X;
    Int32 newY = _printProperties.GridBounds.Y - e.MarginBounds.Y;
    e.Graphics.TranslateTransform(newX, newY);
    _gridRenderer.PrintPage(e, _currentPage - 1);  //grid control's print method
    e.HasMorePages = _currentPage < _printProperties.Document.PrinterSettings.ToPage;
    _currentPage++;
}

private void DrawHeadersAndFooters(Graphics graphics, Rectangle marginBounds)
{
    Rectangle textRect = new Rectangle();
    Int32 height = 0;
    //loop lines in header paragraph to get total height required
    //there are actually three, across the page, but just one example for bevity...
    if (!String.IsNullOrEmpty(_printProperties.HeaderLeft))
    {
        Int32 h = 0;
        foreach (String s in _printProperties.HeaderLeft.Split(new String[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
            h += (Int32)graphics.MeasureString(s, _printProperties.HeaderLeftFont, width, stringFormat).Height;
        height = (h > height) ? h : height;
    } //repeat for other two, keeping the greatest of 3 heights in the end
    textRect.X = marginBounds.X;
    textRect.Y = (Int32)_printProperties.Document.DefaultPageSettings.PrintableArea.Y;  //a global storage for printing information I need to keep in memory
    textRect.Width = width;
    textRect.Height = height;

    stringFormat.Alignment = StringAlignment.Near;
    graphics.DrawString(_printProperties.HeaderLeft, _printProperties.HeaderLeftFont, new SolidBrush(_printProperties.HeaderLeftForeColor), textRect, stringFormat);

    _printProperties.GridBounds = new Rectangle(marginBounds.X, textRect.Y, marginBounds.Width, marginBounds.Bottom - textRect.Y);  //here I think I have the space into which the grid _should_ be made to fit
}

您可以在PrintDocument_PrintPage()中看到我正在对Graphics对象应用转换,该对象将网格向下移动到位,并在标题下。

截图:

enter image description here

所以,问题是:

我想从下到上缩小该区域以使该网格的底部位于页脚之上。您可以通过查看右下角看到渲染的网格图像与我已经绘制的页脚重叠。这就是我需要的帮助。如何在不执行Graphics之类的情况下缩小ScaleTransform()绘图空间,这看起来根本不是正确的想法。

1 个答案:

答案 0 :(得分:1)

答案证明是对逻辑的完全重组。我没有尝试全部解决并同时渲染它,而是将计算代码重构为一个单独的方法,我可以在调用PrintDocument.Print()之前调用它。

这一切都归结为我以前没有意识到的这个小宝石:

Graphics graphics = _printProperties.Document.PrinterSettings.CreateMeasurementGraphics();

这给了我一个新的Graphics对象用于打印文档,我可以用它在打印之前完成所有计算。有了这个,就可以将它存储起来,然后在实际的页眉和页脚渲染中使用结果。

它还为我提供了在网格Margins来电之前调整PrintDocument.DefaultPageSettings的{​​{1}}所需的信息。

一些参考代码:

Print()

请注意,由于我手动绘制所有页眉/页脚文本,因此页边距对其没有影响,因此仅调整 会影响网格渲染。