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