在Windows.Forms中绘图

时间:2017-02-08 16:30:38

标签: c# .net winforms

我有一个简单的Windows.Forms表格。

我想用Color.Aqua填充pictureBox1并绘制一个矩形。

然而,没有任何东西被淹死,直到我移动表格。

为什么会这样?

如何在不移动表单的情况下强制绘制所有内容?

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private readonly Graphics _graphics;
        private List<PointF> _points;
        private Bitmap _bitmap;

        public Form1()
        {
            InitializeComponent();
            _bitmap = new Bitmap(1000, 600);
            _graphics = Graphics.FromImage(_bitmap);
            pictureBox1.Image = _bitmap;

            var timer = new Timer
            {
                Interval = 1
            };
            timer.Tick += OnTick;
            timer.Start();
            Invalidate();
        }

        private void OnTick(object sender, EventArgs e)
        {
            _graphics.Clear(Color.Aqua);
           _graphics.DrawRectangle(Pens.Black, 10, 10, 10, 10);
            Invalidate();
        }
    }
}

3 个答案:

答案 0 :(得分:2)

您必须订阅图片框的Paint事件并将图片代码放在那里,如下所示:

public Form1()
{
    InitializeComponent();
    pictureBox1.Paint += PictureBox1_Paint;
}

private void PictureBox1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.Clear(Color.Aqua);
    e.Graphics.DrawRectangle(Pens.Black, 10, 10, 10, 10);
}

每次需要重新绘制控件时都会引发此事件,因此您不需要Timer技巧或调用Invalidate

答案 1 :(得分:1)

我发现了四个问题:

  1. 为表单调用Invalidate()方法。这个应该使PictureBox无效,但你可以通过直接使PictureBox无效来做得更好。
  2. 您正在绘制位图,但不会更新PictureBox的Image属性。
  3. 一毫秒的间隔会杀了你。 50到100更合理,任何小于17的东西都可能比显示器的刷新率更快。
  4. 使用单独图形的整个内容是额外的,不需要。 pictureBox拥有自己的图形上下文,你可以更好地使用它。
  5. 把它们放在一起,你就明白了:

    public partial class Form1 : Form
    {
        private Timer _timer;
        private List<PointF> _points;
    
        public Form1()
        {
            InitializeComponent();
    
            _timer = new Timer(100);
            timer.Tick += OnTick;
            timer.Start();
        }
    
        private void OnTick(object sender, EventArgs e)
        {
            pictureBox1.Invalidate();
        }
    
        private void PictureBox1_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.Clear(Color.Aqua);
            e.Graphics.DrawRectangle(Pens.Black, 10, 10, 10, 10);
        }
    }
    

答案 2 :(得分:1)

您根本不需要Invalidate()调用,因为您正在绘制缓冲区(Bitmap)。只需将位图设置为pictureBox1.Image属性:

    private void OnTick(object sender, EventArgs e)
    {
        _graphics.Clear(Color.Aqua);
        _graphics.DrawRectangle(Pens.Black, 10, 10, 10, 10);
        pictureBox1.Image = _bitmap;
    }