【问题标题】:Print the entire area of the control with C#使用 C# 打印控件的整个区域
【发布时间】:2014-07-12 20:58:09
【问题描述】:

这不是一个重复的问题——我的问题和其他问题之间的区别是我的控制器包含一个滚动条,因此无法打印更多信息。

我有一个 C# 应用程序,其中包含一个主窗体名称 MainForms。这个MainForms 有一个控件mainDisplay。我想将我们在mainDisplay 上找到的全部信息打印到打印机上。

问题是控件上的信息太大,我必须滚动才能看到所有信息。

有人有什么功能可以让我打印这个控件MainDisplay,里面有完整的信息吗?

这是我的MainDisplay 区域的打印屏幕,您可以在右侧看到滚动条:

我使用这个函数(来源:Printing a control

private static void PrintControl(Control control)
{
    var bitmap = new Bitmap(control.Width, control.Height);

    control.DrawToBitmap(bitmap, new Rectangle(0, 0, control.Width, control.Height));

    var pd = new PrintDocument();

    pd.PrintPage += (s, e) => e.Graphics.DrawImage(bitmap, 100, 100);
    pd.Print();
}

但是我的问题还是不能打印我控件中包含的所有信息,它只是打印了一个小区域,还需要打印更多没有打印的信息。

【问题讨论】:

  • 这不是一个重复的问题 - 我的问题和其他问题之间的区别是我的控制器包含一个滚动条,因此无法打印更多信息。
  • 很难想象,这会一遍又一遍地出现。像这样的打印控件有很多问题,滚动是解决问题的较小(并且几乎不可能)的问题。更严重的是显示器和打印机之间分辨率的巨大差异。屏幕上的每一个像素都会在纸上被放大成 6x6 的墨迹。文本看起来特别差,使文本在低分辨率显示器上可读的抗锯齿像素在纸上变成难看的高度可见的斑点。编写一个采用 Graphics 对象参数并绘制网格的方法。现在你可以调用它了。

标签: c# winforms printing


【解决方案1】:

我找到了解决方案。这是我要做的步骤:

1 - 我们有一个mainForm,这个主窗体包含一个具有特定尺寸和区域的控件mainDisplay,假设这个尺寸更小,我们可以滚动。

2- 我所做的就是把这个mainDisplay 清空。

3- 我创建了另一个控件myControlToDisplay。我绘制并放置所有我想要的字段而不滚动,所以这个myControlToDisplay 将有一个很大的维度。

4- 在我的应用程序启动时,我告诉mainDisplay 加载myControlToDisplay。这一次myControlToDisplay 的所有内容将在mainDisplay 上滚动显示。因为mainDisplay的面积很小。

5- 我写了这个函数:

Bitmap MemoryImage;
PrintDocument printDoc = new PrintDocument();
PrintDialog printDialog = new PrintDialog();
PrintPreviewDialog printDialogPreview = new PrintPreviewDialog();
Control panel = null;

public void Print(Control pnl)
{
    DateTime saveNow = DateTime.Now;
    string datePatt = @"yyyy-M-d_hh-mm-ss tt";

    panel = pnl;
    GetPrintArea(pnl);
    printDialog.AllowSomePages = true;
    printDoc.PrintPage += new PrintPageEventHandler(Print_Details);
    printDialog.Document = printDoc;
    printDialog.Document.DocumentName = "Document Name";

    //printDialog.ShowDialog();
    if (printDialog.ShowDialog() == DialogResult.OK)
    {
        printDoc.Print();
    }
}

public void PrintPreview(Control pnl)
{
    DateTime saveNow = DateTime.Now;
    string datePatt = @"yyyy-M-d_hh-mm-ss tt";

    panel = pnl;
    GetPrintArea(pnl);           
    printDoc.PrintPage += new PrintPageEventHandler(Print_Details);
    printDialogPreview.Document = printDoc;
    printDialogPreview.Document.DocumentName = "Document Name";

    //printDialog.ShowDialog();
    if (printDialogPreview.ShowDialog() == DialogResult.OK)
    {
        printDoc.Print();
    }
}

private void Print_Details(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
    RectangleF marginBounds = e.MarginBounds;

    DateTime saveNow = DateTime.Now;
    string datePatt = @"M/d/yyyy hh:mm:ss tt";
    //String dtString = saveNow.ToString(datePatt);

    // create header and footer
    string header = "Put all information you need to display on the Header";
    string footer = "Print date : " + saveNow.ToString(datePatt);

    Font font = new Font("times new roman", 10, System.Drawing.FontStyle.Regular);
    Brush brush = new SolidBrush(Color.Black);

    // measure them
    SizeF headerSize = e.Graphics.MeasureString(header, font);
    SizeF footerSize = e.Graphics.MeasureString(footer, font);

    // draw header
    RectangleF headerBounds = new RectangleF(marginBounds.Left-80, marginBounds.Top-80, marginBounds.Width, headerSize.Height);
    e.Graphics.DrawString(header, font, brush, headerBounds);

    // draw footer
    RectangleF footerBounds = new RectangleF(marginBounds.Left-80, marginBounds.Bottom - footerSize.Height+80, marginBounds.Width, footerSize.Height);
    e.Graphics.DrawString(footer, font, brush, footerBounds);

    // dispose objects
    font.Dispose();
    brush.Dispose();
}

public void GetPrintArea(Control pnl)
{
    MemoryImage = new Bitmap(pnl.Width, pnl.Height);
    Rectangle rect = new Rectangle(0, 0, pnl.Width, pnl.Height);
    pnl.DrawToBitmap(MemoryImage, new Rectangle(0, 0, pnl.Width, pnl.Height));
}

protected override void OnPaint(PaintEventArgs e)
{
    if (MemoryImage != null)
    {
        e.Graphics.DrawImage(MemoryImage, 0, 0);
        base.OnPaint(e);
    }
}
void PrintDoc_PrintPage(object sender, PrintPageEventArgs e)
{
    Rectangle pageArea = e.PageBounds;
    Rectangle m = e.MarginBounds;

    if ((double)MemoryImage.Width / (double)MemoryImage.Height > (double)m.Width / (double)m.Height) // image is wider
    {
        m.Height = (int)((double)MemoryImage.Height / (double)MemoryImage.Width * (double)m.Width);
    }
    else
    {
        m.Width = (int)((double)MemoryImage.Width / (double)MemoryImage.Height * (double)m.Height);
    }

    e.Graphics.DrawImage(MemoryImage, m);

}

6 - 最后我们假设我们有两个按钮,一个用于打印,另一个用于打印预览。 你只需要调用这个函数:

private void PrintButton_Click(object sender, EventArgs e)
{
    try
    {
        Print(mainDisplay.getCurentPanel());
    }
    catch (Exception exp)
    {
        MessageBox.Show("Error: \n" + exp.Message);
    }
}

private void PrintPreviewButton_Click(object sender, EventArgs e)
{
    try
    {
        PrintPreview(mainDisplay.getCurentPanel());
    }
    catch (Exception exp)
    {
        MessageBox.Show("Error: \n" + exp.Message);
    }
}

希望对某人有所帮助:)

祝你好运

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-12
    相关资源
    最近更新 更多