如何使用c#绘制多个矩形

时间:2010-06-01 09:13:03

标签: c#

我已经在图片框中加载的图像上绘制并保存了矩形。我喜欢在矩形中为我尝试过的数组绘制多个矩形,但是它给出了错误(“对象引用未设置为对象的实例。”(空引用异常未处理)。

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    if (mybitmap == null)
    {
        mybitmap = new Bitmap(sz.Width, sz.Height);
    }
    rect[count] = new Rectangle(e.X, e.Y, 0, 0);
    this.Invalidate();
}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (stayToolStripMenuItem.Checked == true)
    {
        switch (e.Button)
        {
            case MouseButtons.Left:
            {
                rect[count] = new Rectangle(rect[count].Left, rect[count].Top, e.X - rect[count].Left, e.Y - rect[count].Top);
                pictureBox1.Invalidate();
                count++:
                break;
            }      
        }
    }
}

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    if (stayToolStripMenuItem.Checked == true)
    {
        button1.Visible = true;
        button2.Visible = true;

        if (mybitmap == null)
        {
            return;
        }

        using (g = Graphics.FromImage(mybitmap))
        {
            using (Pen pen = new Pen(Color.Red, 2))
            {
                //g.Clear(Color.Transparent);
                e.Graphics.DrawRectangle(pen, rect);
                label1.Top = rect[count].Top; label1[count].Left = rect[count].Left; label1.Width = rect[count].Width;
                label1.Height = rect[count].Height;

                if (label1.TextAlign == ContentAlignment.TopLeft)
                {
                    e.Graphics.DrawString(label1.Text, label1.Font, new SolidBrush(label1.ForeColor), rect);
                    g.DrawString(label1.Text, label1.Font, new SolidBrush(label1.ForeColor), rect);
                    g.DrawRectangle(pen, rect[count]);
                }
            }
        }
    }
}

我怎么能这样做.....

2 个答案:

答案 0 :(得分:3)

在填充count数组后,您正在递增rect变量。在执行pictureBox1_Paint时,此增量已经发生,因此rect[count]现在是一个空引用,然后您尝试绘制:)

此外,pictureBox1_MouseDown中似乎存在编译器错误。 count++语句中的switch不属于任何case块。把它放在break;陈述之前。

我想你的意图是这样的:

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    if (mybitmap == null)
       return;

    using (g = Graphics.FromImage(mybitmap))
    using (Pen pen = new Pen(Color.Red, 2))
    {
        g.Clear(Color.Transparent);

        for (int i = 0; i < count; i++)
        {
            // Code to draw rect[i], instead of rect[count]
        }
    }
}

顺便说一句,你的rect数组有多大?数组不会自动增长以满足您的需求。您可能希望改为使用List<Rectangle>

答案 1 :(得分:0)

稍微改变一下代码。而不是鼠标移动事件使用鼠标单击事件。

在使用鼠标移动事件时,每当鼠标在图片框上移动时,它都会调用。所以列表矩形计数增加了。为此,我使用鼠标点击事件。

在鼠标按下事件中添加列表矩形时,它只获取矩形(if use (0,0,e.X,e.Y))的高度和宽度值,并且矩形始终从左上角开始(无法启动用户的矩形点)喜欢)并且它只获得XY值(if use(e.X, e.Y,0,0)

为了解决这个问题,我在鼠标点击事件中使用了列表矩形,因此我获得了所有值。

List<Rectangle> rectangles = new List<Rectangle>();

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        if (stayToolStripMenuItem.Checked == true)
        {

            if (mybitmap == null)
            {
                mybitmap = new Bitmap(sz.Width, sz.Height);

            }
            rect = new Rectangle(e.X, e.Y, 0, 0);
            this.Invalidate();

        }

    }


    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        if (stayToolStripMenuItem.Checked == true)
        {
            button1.Visible = true;
            button2.Visible = true;

            if (mybitmap == null)
            {
                return;
            }


                using (g = Graphics.FromImage(mybitmap))
                {

                    using (Pen pen = new Pen(Color.Red, 2))
                    {
                        //g.Clear(Color.Transparent);


                        e.Graphics.DrawRectangle(pen, rect);
                        label1.Top = rect.Top; label1.Left = rect.Left; label1.Width = rect.Width;
                        label1.Height = rect.Height;


                        if (label1.TextAlign == ContentAlignment.TopLeft)
                        {
                            e.Graphics.DrawString(label1.Text, label1.Font, new SolidBrush(label1.ForeColor), rect);
                            g.DrawString(label1.Text, label1.Font, new SolidBrush(label1.ForeColor), rect);
                            g.DrawRectangle(pen, rect);

                        }

                    }

                }

private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
    {

            if (e.Button == MouseButtons.Left)

            {
                rect = new Rectangle(rect.Left, rect.Top, e.X - rect.Left, e.Y - rect.Top);
                rectangles.Add(rect);
                pictureBox1.Invalidate();
                f = 0;

            }


    }

我绘制的任何矩形都会保存在列表矩形中并在保存工作时保存(当我打开保存的文件时可以看到所有绘制的矩形)。

现在的问题是,当我绘制一个新的矩形时,前一个矩形消失了(在运行时。但是这在列表矩形中添加了。)

如何显示在运行时绘制的所有矩形,以便用户可以知道绘制的矩形数量和位置。