英文:
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();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。



评论