PictureBox的Paint事件导致轻弹 - 我还能在哪里做到这一点?

时间:2012-07-23 03:12:54

标签: c# winforms compact-framework windows-mobile-6.5

我正在使用Psion的SDK在移动设备上提供签名控制。 我想在签名控件(这是一个图片框)周围绘制一个矩形。 我已将以下内容放入Paint事件中,但问题是它闪烁(当您在图片框中登录时,图片框会不断刷新。

有没有办法把它放到表单的load事件中,所以它只加载一次? 我知道它需要有PainEventArgs,但我对此并不十分肯定。

    private void scSignature_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.DrawRectangle(new Pen(Color.Black, 2f), 0, 0,
            e.ClipRectangle.Width - 1,
            e.ClipRectangle.Height - 1
            );
    }

由于

2 个答案:

答案 0 :(得分:7)

在CF中绘画时防止闪烁和垃圾创建的提示:

  1. 覆盖OnPaintBackground并将其留空
  2. 如果您有多项操作,请不要直接向Graphics提交给您。而是创建一个Bitmap缓冲区,绘制到该缓冲区,然后将该位图的内容绘制到Graphics
  3. 不要使用每个Paint在#2中创建缓冲区。创建一个并重复使用它。
  4. 不要重绘静态项目(如签名控件中的框)。相反,将其绘制到缓冲的Bitmap,将该位图绘制到#2中的缓冲区,然后绘制动态项目
  5. 不要使用每个Paint创建钢笔,画笔等。缓冲和重用。
  6. 在您的情况下,这些建议可能如下所示:

    class Foo : Form
    {
        private Bitmap m_background;
        private Bitmap m_backBuffer;
        private Brush m_blackBrush;
        private Pen m_blackPen;
    
        public Foo()
        {
            m_blackBrush = new SolidBrush(Color.Black);
            m_blackPen = new Pen(Color.Black, 2);
    
            // redo all of this on Resize as well
            m_backBuffer = new Bitmap(this.Width, this.Height);
            m_background = new Bitmap(this.Width, this.Height);
            using (var g = Graphics.FromImage(m_background))
            {
                // draw in a static background here
               g.DrawRectangle(m_blackBrush, ...);
                // etc.
            }
        }
    
        protected override void OnPaintBackground(PaintEventArgs e)
        {
        }
    
        protected override void  OnPaint(PaintEventArgs e)
        {
            using (var g = Graphics.FromImage(m_backBuffer))
            {
                // use appropriate back color
                // only necessary if the m_background doesn't fill the entire image
                g.Clear(Color.White);
    
                // draw in the static background
                g.DrawImage(m_background, 0, 0);
    
                // draw in dynamic items here
                g.DrawLine(m_blackPen, ...);
            }
    
            e.Graphics.DrawImage(m_backBuffer, 0, 0);         
        } 
    }
    

答案 1 :(得分:0)

这肯定不是一种优雅的方法,但是如果你可以确保你的图片框根本没有边框,你可以在picturebox容器控件上绘制一个实心矩形。 将它放在图片框的正后方,使其四周都宽1px,因此它看起来像图片框周围的1px边框。

可能的示例(覆盖包含图片框的控件的OnPaint方法):

protected override OnPaint(object sender, PaintEventArgs e)
{
     base.OnPaint(sender, e);
     int x = scSignature.Location.X - 1;
     int y = scSignature.Location.Y - 1;
     int width = scSignature.Size.Width + 2;
     int height = scSignature.Size.Height + 2;
     using (Brush b = new SolidBrush(Color.Black))
     {
        e.Graphics.FillRectangle(b,x,y,width,height);
     }

}