今天接到任务 ,做一个类似话费单的打印。要求很简单,就是可以精确的更改打印的内容的位置,还有就是打印出模板(打印的内容当然是可以替换喽)
Form窗体中包含:一个PictureBox(显示背景图片),两个Label(一个姓名,一个地址),一个Button(打印按钮)
这个问题的关键有三点:
1:怎么把Label做成透明的,如果是直接加载在Form上的话,是没有办法显示的,Label的透明是相对于它的父容器的,这就要求每次重绘的同时把它加载到PictureBox中,因为winforms 默认加载到Fom上
2:处理好事件之间的关系,关于拖动Label控件和窗体事件的混合
private bool isMove =false;
private int MouseDownX;
private int MouseDownY;
/// <summary>
///在图片控件上放开鼠标时触发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
isMove = false;
}
/// <summary>
/// Label控件按下鼠标时触发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lbName_MouseDown(object sender, MouseEventArgs e)
{
isMove = true;
MouseDownX = e.X;
MouseDownY = e.Y;
}
/// <summary>
/// 在Label上的鼠标放开时触发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lbName_MouseUp(object sender, MouseEventArgs e)
{
isMove = false;
}
/// <summary>
/// 鼠标在在Label上移动时触发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lbName_MouseMove(object sender, MouseEventArgs e)
{
if(isMove)//如果左键按下的话
{
((Label)sender).Location = new Point(((Label)sender).Left + e.X - MouseDownX, ((Label)sender).Top + e.Y - MouseDownY);
this.pictureBox1.Controls.Add(((Label)sender));
}
}
/// <summary>
/// 在PicturesBox控件上移动时触发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if(isMove)//如果作家安按下的话
{
((Label)sender).Location = new Point(e.X - MouseDownX, e.Y - MouseDownY);
this.pictureBox1.Controls.Add(((Label)sender));
}
}
在做这个Demo的时候 我发现 原来当鼠标点击在Label上时是没有有办法捕捉到PictureBox的移动方法(pictureBox1_MouseMove),故:采用上述方法,最后实现了
3:关于打印 呵呵 我也是费了点心思
上网查了好多资料,关键点如下:
1:怎么打印winforms窗体中指定的区域呢?
最后查到是写到剪贴板上,呵呵 挺微妙 微软就是好
2:绘图的时候我是用了DrawImage方法,绘制了制定区域的图像,但有个问题没有弄,这只是一个Demo ,没必要弄那么细。就是边距问题,不能完全匹配,左上角有点出入。
private void btnPrint_Click(object sender, EventArgs e)
{
SendKeys.Send("%{PRTSC}");
Application.DoEvents();
this.printDocument1.PrintPage += new PrintPageEventHandler(docToPrint_PrintPage);
printDialog1.Document = printDocument1;
printDocument1.Print();
}
private void docToPrint_PrintPage(object sender, PrintPageEventArgs ev)
{
int left = this.pictureBox1.Left;
int top = this.pictureBox1.Top;
int width = this.pictureBox1.Width;
int height = this.pictureBox1.Height;
int HeadHeight = SystemInformation.CaptionHeight;//标准的标题栏高度
IDataObject iData = Clipboard.GetDataObject();
Image img = (Image)iData.GetData(DataFormats.Bitmap);
Rectangle recTo = new Rectangle(left+5, top + HeadHeight+10, width, height);
//最后没有匹配,可能是像网页中存在margin一样的和模型的缘故吧 呵呵 ,要是项目搞到了 好好研究研究
Rectangle recFrom = new Rectangle(0, 0, this.Width, this.Height);
ev.Graphics.DrawImage(img, recFrom, recTo, GraphicsUnit.Pixel);
}