无法在图片内打印标签

huangapple go评论86阅读模式
英文:

Can't print label inside a picture

问题

尽管在 Show() 后表单呈现如预期,但在将图像绘制到画布时,当标签位于图片内部时,标签似乎会消失,无论是 PictureBox 还是带有背景图像的标签。

进一步检查后,似乎即使将它发送到后面,图片也会被绘制在前面。有什么解决方案吗?

无法在图片内打印标签

public partial class SampleForm: Form
{
    public SampleForm()
    {
        InitializeComponent();
        label1.BringToFront(); //带有背景颜色的普通标签

        label2.SendToBack(); //带有背景图像的标签
    }


    Bitmap original;
    Bitmap bitMaptoPrint;
    private void captureFromScreen()
    {
        
       original = new Bitmap(panel1.Width, panel1.Height);
       panel1.DrawToBitmap(original, new Rectangle(0, 0, panel1.Width, panel1.Height));
       bitMaptoPrint = new Bitmap(original, new Size(816, 1056));
    }

    private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
        Rectangle m = new Rectangle(0, 0, 816, 1056);
        e.Graphics.DrawImage(bitMaptoPrint, m);
    }

    private void button1_Click_1(object sender, EventArgs e)
    {
        captureFromScreen();
        printPreviewDialog1.ShowDialog();
    }

}
英文:

Although the form render as expected after Show(), when it's time to draw the image to the canvas the label seems to disappear when it's inside a picture whether it's a PictureBox or Label with a bg image.

Upon further checking it looks like the picture is being drawn at front even when I'm sending it to back. Any solutions?

无法在图片内打印标签

  public partial class SampleForm: Form
{
    public SampleForm()
    {
        InitializeComponent();
        label1.BringToFront(); //plain label with bg color

        label2.SendToBack(); //label with a bg image
    }


    Bitmap original;
    Bitmap bitMaptoPrint;
    private void captureFromScreen()
    {
        
       original = new Bitmap(panel1.Width, panel1.Height);
       panel1.DrawToBitmap(original, new Rectangle(0, 0, panel1.Width, panel1.Height));
       bitMaptoPrint = new Bitmap(original,new Size(816, 1056));
    }

    private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
        Rectangle m = new Rectangle(0, 0, 816, 1056);
        e.Graphics.DrawImage(bitMaptoPrint, m);
    }

    private void button1_Click_1(object sender, EventArgs e)
    {
        captureFromScreen();
        printPreviewDialog1.ShowDialog();
    }

}

答案1

得分: 2

以下是代码的翻译部分:

一种选择是通过实际使用Graphics.CopyFromScreen()来实现您的captureFromScreen()方法。这样应该是所见即所得(WYSIWYG),有助于避免您在评论中描述的“尴尬”和不断变换的Z顺序。

PrintPreviewDialog _printPreview = new PrintPreviewDialog();
private void captureFromScreen()
{
    Bitmap bitmap = new Bitmap(panel.Width, panel.Height);
    var screenLocation = PointToScreen(panel.Location);
    using (var graphics = Graphics.FromImage(bitmap))
    {
        graphics.CopyFromScreen(screenLocation, Point.Empty, panel.Size);
    }

    PrintDocument document = new PrintDocument();
    document.PrintPage += localPrintPage;
    _printPreview.Document = document;

    _printPreview.ShowDialog();

    void localPrintPage(object sender, PrintPageEventArgs e)
    {
        e.Graphics?.DrawImage(
            bitmap,
            (e.PageBounds.Width - bitmap.Width) / 2,
            (e.PageBounds.Height - bitmap.Height) / 2,
            bitmap.Width,
            bitmap.Height);
    }
}

测试

无法在图片内打印标签

public partial class MainForm : Form, IMessageFilter
{
    public MainForm()
    {
        InitializeComponent();
        Application.AddMessageFilter(this);
        Disposed += (sender, e) => Application.RemoveMessageFilter(this);

        Label label = new Label
        {
            Name = "label1",
            Text = "Label",
            Location = new Point(0, panel.Height / 2),
            Size = new Size(panel.Width, 80),
            BackColor = Color.FromArgb(231, 134, 131),
            TextAlign = ContentAlignment.MiddleCenter,
        };
        panel.BackColor = Color.Azure;
        panel.Controls.Add(label);
        panel.Controls.SetChildIndex(label, 0);
    }
    const int WM_KEYDOWN = 0x0100;
    public bool PreFilterMessage(ref Message m)
    {
        if (m.Msg.Equals(WM_KEYDOWN))
        {
            switch ((Keys)m.WParam | ModifierKeys)
            {
                case Keys.Control | Keys.P:
                    BeginInvoke(new Action(() => captureFromScreen()));
                    return true;
            }
        }
        return false;
    }
    // ...
}

请注意,代码中的"被替换为正常的双引号"以表示字符串。

英文:

One option would be to implement your captureFromScreen() method by really capturing the screen using Graphics.CopyFromScreen(). This way it should be WYSIWYG (helping avoid the "awkward" and constant shifting of the z-order you describe in your comment).

PrintPreviewDialog _printPreview = new PrintPreviewDialog();
private void captureFromScreen()
{
    Bitmap bitmap = new Bitmap(panel.Width, panel.Height);
    var screenLocation = PointToScreen(panel.Location);
    using (var graphics = Graphics.FromImage(bitmap))
    {
        graphics.CopyFromScreen(screenLocation, Point.Empty, panel.Size);
    }

    PrintDocument document = new PrintDocument();
    document.PrintPage += localPrintPage;
    _printPreview.Document= document;

    _printPreview.ShowDialog();

    void localPrintPage(object sender, PrintPageEventArgs e)
    {
        e.Graphics?.DrawImage(
            bitmap,
                (e.PageBounds.Width - bitmap.Width) / 2,
                (e.PageBounds.Height - bitmap.Height) / 2,
                bitmap.Width,
                bitmap.Height);
    }
}

Test

无法在图片内打印标签

public partial class MainForm : Form, IMessageFilter
{
    public MainForm()
    {
        InitializeComponent();
        Application.AddMessageFilter(this);
        Disposed += (sender, e) => Application.RemoveMessageFilter(this);

        Label label = new Label
        {
            Name = "label1",
            Text = "Label",
            Location = new Point(0, panel.Height/2),
            Size = new Size(panel.Width, 80),
            BackColor= Color.FromArgb(231, 134, 131),
            TextAlign = ContentAlignment.MiddleCenter,
        };
        panel.BackColor = Color.Azure;
        panel.Controls.Add(label);
        panel.Controls.SetChildIndex(label, 0);
    }
    const int WM_KEYDOWN = 0x0100;
    public bool PreFilterMessage(ref Message m)
    {
        if(m.Msg.Equals(WM_KEYDOWN))
        {
            switch((Keys)m.WParam | ModifierKeys) 
            {
                case Keys.Control | Keys.P:
                    BeginInvoke(new Action(()=> captureFromScreen()));
                    return true;
            }
        }
        return false;
    }
    .
    .
    .
}

答案2

得分: 0

问题出在DrawToBitmap()在容器中绘制控件时是以相反的顺序进行的。解决方法非常简单,只需在每次打印之前将其移到最底层。

private void button1_Click_1(object sender, EventArgs e)
{
    picturebox1.sendToBack();
    captureFromScreen();
    printPreviewDialog1.ShowDialog();
}
英文:

The problem comes from the fact that DrawToBitmap() draw controls inside containers in reverse order. Solution is pretty straightforward just bring it to back, before every print.

private void button1_Click_1(object sender, EventArgs e)
{
    picturebox1.sendToBack();
    captureFromScreen();
    printPreviewDialog1.ShowDialog();
}

huangapple
  • 本文由 发表于 2023年2月26日 23:02:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/75572857.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定