2016-11-10 73 views
1

我使用WinForms创建时钟。问题是时钟手正在我的面板/标签下。我试图在我的面板/标签上绘制手,但我没有成功。我也尝试将我的面板/标签移动到后面,并将手放在前面,这也不能很好地工作。我也尝试做一些像这样做的透明面板panel_digital_Timer.Parent = pictureBox1。我怎样才能将时钟放在面板/标签前面?模拟时钟 - 在标签上绘制时钟手臂

public partial class Form1 : Form 
{ 
    private Bitmap bmp; 
    private int angle = 0; 
    private int counter_Time; 


    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     pictureBox1.Paint += PictureBox1_Paint; 
     bmp = Properties.Resources.Clock_Arm; 

     //pictureBoxOverlay.BackColor = Color.Transparent; 

     //// Change parent for overlay PictureBox... 
     pictureBoxOverlay.Parent = pictureBox1; 

     panel_digital_Timer.BackColor = Color.Transparent; 
    } 

    private void PictureBox1_Paint(object sender, PaintEventArgs e) 
    { 
     var rbmp = rotateCenter(bmp, angle); 
     e.Graphics.TranslateTransform((pictureBox1.Width - rbmp.Width)/2, 
      (pictureBox1.Height - rbmp.Height)/2); 
     e.Graphics.DrawImage(rbmp, 0, 0); 
     e.Graphics.ResetTransform(); 
    } 


    /// <summary> 
    /// Rotates the input image by theta degrees around center. 
    /// </summary> 
    public static Bitmap rotateCenter(Bitmap bmpSrc, float theta) 
    { 
     Matrix mRotate = new Matrix(); 
     //mRotate.Translate(bmpSrc.Width/-2, bmpSrc.Height/-2, MatrixOrder.Append); 
     mRotate.Translate(bmpSrc.Width/-2, -bmpSrc.Height, MatrixOrder.Append); 
     mRotate.RotateAt(theta, new Point(0, 0), MatrixOrder.Append); 
     using (GraphicsPath gp = new GraphicsPath()) 
     { // transform image points by rotation matrix 
      gp.AddPolygon(new Point[] { new Point(0, 0), new Point(bmpSrc.Width, 0), new Point(0, bmpSrc.Height) }); 
      gp.Transform(mRotate); 
      PointF[] pts = gp.PathPoints; 

      // create destination bitmap sized to contain rotated source image 
      Rectangle bbox = boundingBox(bmpSrc, mRotate); 
      Bitmap bmpDest = new Bitmap((int)(bbox.Width * 2), (int)(bbox.Height * 2)); 

      using (Graphics gDest = Graphics.FromImage(bmpDest)) 
      { // draw source into dest 
       Matrix mDest = new Matrix(); 
       //mDest.Translate(bmpDest.Width/2, bmpDest.Height/2, MatrixOrder.Append); 
       mDest.Translate(bmpDest.Width/2, bmpDest.Height/2, MatrixOrder.Append); 
       gDest.Transform = mDest; 
       gDest.DrawImage(bmpSrc, pts); 
       //drawAxes(gDest, Color.Red, 0, 0, 1, 100, ""); 
       return bmpDest; 
      } 
     } 
    } 

    private static Rectangle boundingBox(Image img, Matrix matrix) 
    { 
     GraphicsUnit gu = new GraphicsUnit(); 
     Rectangle rImg = Rectangle.Round(img.GetBounds(ref gu)); 

     // Transform the four points of the image, to get the resized bounding box. 
     Point topLeft = new Point(rImg.Left, rImg.Top); 
     Point topRight = new Point(rImg.Right, rImg.Top); 
     Point bottomRight = new Point(rImg.Right, rImg.Bottom); 
     Point bottomLeft = new Point(rImg.Left, rImg.Bottom); 
     Point[] points = new Point[] { topLeft, topRight, bottomRight, bottomLeft }; 
     GraphicsPath gp = new GraphicsPath(points, 
     new byte[] { (byte)PathPointType.Start, (byte)PathPointType.Line, (byte)PathPointType.Line, (byte)PathPointType.Line }); 
     gp.Transform(matrix); 
     return Rectangle.Round(gp.GetBounds()); 
    } 

    private void Timer_StopClock_Tick(object sender, EventArgs e) 
    { 
     if (counter_Time == 360) 
     { 
      counter_Time = 0; 
     } 
     else 
     { 
      counter_Time += 15; 
     } 

     angle = counter_Time; 
     //angle += counter_Time; 

     Console.WriteLine(counter_Time); 
     pictureBox1.Invalidate(); 
    } 
} 

下载项目:http://www.filedropper.com/clockprojectquestion

目标

enter image description here

问题

enter image description here

+0

没有看到你的设计师代码,我不能肯定地说,但如果标签在Z顺序上位于最前面,它将在您的自定义绘画之后被绘制。我要么在Z顺序的顶部创建一个完全透明的控件,在最后画出手。另外,你的位图是透明的吗?如果没有绘画,最后可能会覆盖您的标签。 –

+3

不要使用'TextBox'来显示文本,只需使用'TextRenderer.DrawText'绘制文本。 –

+0

@SeanK设计器代码在我的可下载链接中粘贴在我的问题中。 – taji01

回答

2

请勿使用TextBox来显示文本,自己绘制文本。

您在Control的对象Graphics上绘制的图形将绘制在控件的表面上,并且不能绘制在子控件或其他堆叠控件上。因此,在上面的代码中,而不是使用TextBox来显示文本,您应该使用TextRenderer.DrawText来绘制文本。

手柄Interval组定时器1000的Tick事件和在Tick事件处理程序调用pictureBox1.Invalidate();。然后,在手柄Paint事件中的图片框的这样:

private void pictureBox1_Paint(object sender, PaintEventArgs e) 
{ 
    var g = e.Graphics; 
    g.SmoothingMode = SmoothingMode.AntiAlias; 
    g.Clear(Color.White); 
    var r1 = this.pictureBox1.ClientRectangle; 
    r1.Inflate(-3, -3); 
    g.DrawEllipse(Pens.Black, r1); 
    var r2 = r1; 
    r2.Inflate(-5, -5); 
    TextRenderer.DrawText(g, DateTime.Now.ToString("HH:mm:ss"), this.Font, 
     new Rectangle(r1.Left, r1.Top + 2 * r1.Height/3, r1.Width, r1.Height/3), 
     Color.Black); 
    e.Graphics.TranslateTransform(r2.Left + r2.Width/2, r2.Top + r2.Height/2); 
    var c = g.BeginContainer(); 
    g.SmoothingMode = SmoothingMode.AntiAlias; 
    e.Graphics.RotateTransform(DateTime.Now.Hour * 30f + DateTime.Now.Minute/2f); 
    g.FillEllipse(Brushes.Black, -5, -5, 10, 10); 
    using (var p = new Pen(Color.Black, 4)) 
     g.DrawLine(p, 0, 0, 0, -r2.Height/2 + 30); 
    g.EndContainer(c); 
    c = g.BeginContainer(); 
    g.SmoothingMode = SmoothingMode.AntiAlias; 
    e.Graphics.RotateTransform(DateTime.Now.Minute * 6); 
    using (var p = new Pen(Color.Black, 2)) 
     g.DrawLine(p, 0, 0, 0, -r2.Height/2 + 10); 
    g.EndContainer(c); 
    c = g.BeginContainer(); 
    g.SmoothingMode = SmoothingMode.AntiAlias; 
    e.Graphics.RotateTransform(DateTime.Now.Second * 6); 
    using (var p = new Pen(Color.Red, 2)) 
     g.DrawLine(p, 0, 10, 0, -r2.Height/2 + 15); 
    g.EndContainer(c); 
} 

那么结果会是这样:

enter image description here