C#GDI+绘制动态矩形的问题

时间:2022-06-14 08:33:28
 这个问题提了一段时间了,但是因为没有具体代码,所以没有很好的解决,这次贴上代码和效果图,希望各位大大能帮忙解决下,万分感谢!
    主要是先绘制一个图形,然后利用鼠标事件绘制动态绘制矩形,在鼠标移动的时候要求始终只有一个矩形,最后mouseup事件的时候矩形消失。下面附效果图和代码。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication15
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private Point DownPoint = Point.Empty;//记录鼠标按下坐标,用来确定绘图起点
        private bool CatchFinished = false;//用来表示是否截图完成
        private bool CatchStart = false;//表示截图开始
        private Bitmap originBmp;//用来保存原始图像
        private Bitmap MyImage;//进行操作的位图
        //绘制位图实例对象
        private Graphics MyGraphics;
        private void Form1_Load(object sender, EventArgs e)
        {
            //双缓存
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
            this.UpdateStyles();

        }

        private void button1_Click(object sender, EventArgs e)
        {
            Graphics g = this.panel1.CreateGraphics();
            g.Clear(Color.White);
            MyImage = new Bitmap(this.panel1.ClientRectangle.Width, this.panel1.ClientRectangle.Height);
            MyGraphics = Graphics.FromImage(MyImage);
            MyGraphics.Clear(Color.White);
            g.DrawImage(MyImage, panel1.ClientRectangle);
            Pen p = new Pen(Color.Black, 2);
            g.DrawLine(p, 100, 100, 200, 200);
            g.DrawRectangle(p, 200, 200, 200,200);

        }
        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (!CatchStart)
                {
                    CatchStart = true;
                    DownPoint = new Point(e.X, e.Y);
                }
            }
        }
        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            if (CatchStart == true)
            {
                Graphics g = this.panel1.CreateGraphics();
                //panel1_Paint(this, new PaintEventArgs(this.panel1.CreateGraphics(), this.panel1.ClientRectangle));
                //Bitmap bmp = (Bitmap)MyImage.Clone();
                //Graphics g = Graphics.FromImage(bmp);              
                //Pen p = new Pen(Color.Black, 1);
                //CatchRect = new Rectangle(DownPoint.X, DownPoint.Y, e.X - DownPoint.X, e.Y - DownPoint.Y);
                //g.DrawRectangle(p, CatchRect);
                //g.Dispose();
                //p.Dispose();
                //Graphics g1 = this.panel1.CreateGraphics();//在整个全屏窗体上新建画板
                //g1.DrawImage(bmp, new Point(0, 0));//将刚才所画的图片画到这个窗体上
                //g1.Dispose();
                //bmp.Dispose();
                g.DrawRectangle(new Pen(Color.Black, 1), DownPoint.X, DownPoint.Y, e.X - DownPoint.X, e.Y - DownPoint.Y);
            }
        }
        private void panel1_MouseUp(object sender, MouseEventArgs e)
        {
            MyGraphics.DrawRectangle(new Pen(Color.Black, 1), DownPoint.X, DownPoint.Y, e.X - DownPoint.X, e.Y - DownPoint.Y);
            CatchStart = false;
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = this.panel1.CreateGraphics();
            if (MyImage != null)
            {
                g.Clear(Color.White);
                g.DrawImage(MyImage, this.panel1.ClientRectangle);
            }
        }
    }
}
    最后的MOUSEUP的CATCHSTART和CATCHFINISH我没写,主要问题就是要不就是鼠标移动的时候绘制多个矩形,要不就是只绘制一个矩形,但是原来绘制的图形消失了,消失图形那段代码我也写出来了,不过前面标注//。希望各位大大能够给我改进下代码,具体点,非常感谢!

8 个解决方案

#1


需要用到两层,原来的图放到底层,新画的图放上层透明,这样看起来就是完整的。待moseup时再新画的图合成到底图上。
另外,你的Graphics没有进行销毁

#2


仔细的看了一下楼主的代码,你的要求只是画一个矩形而已,不是动态的画,这样主要在mousedown里面记录一个开始坐标,在mouseup里面using(Graphics g = this.panel1.CreateGraphics())
{
//换图代码
}
这样就可以了,但是画出来的矩形框在遮挡后会被刷掉,要是要长久保存的话,那就在paint事件里面用鼠标按下和弹起记录的两个坐标用e.Graphics 画,画出来的矩形可以长久保存。

#3


该回复于2013-06-10 09:15:36被管理员删除

#4


可以参考这个文章来学习下的:
http://www.cnblogs.com/zhili/archive/2013/05/24/3096101.html
希望对你有帮助的

#5


就是做个鼠标拖动的选择框啊,我倒是做了的,拖动是个虚线框,好像c#有虚线框的绘制方法的。就是画那种可以反转颜色的矩形,鼠标移动的时候,搽除掉原来的,再重画一个

#6


这个我是做拓扑图,用来选择拓扑对象的时候用的。

#7


引用 1 楼 WM_JAWIN 的回复:
需要用到两层,原来的图放到底层,新画的图放上层透明,这样看起来就是完整的。待moseup时再新画的图合成到底图上。
另外,你的Graphics没有进行销毁

能不能麻烦写下具体代码,特别是换图的,我会加分的 谢谢!

#8


引用 2 楼 shenwenjie06 的回复:
仔细的看了一下楼主的代码,你的要求只是画一个矩形而已,不是动态的画,这样主要在mousedown里面记录一个开始坐标,在mouseup里面using(Graphics g = this.panel1.CreateGraphics())
{
//换图代码
}
这样就可以了,但是画出来的矩形框在遮挡后会被刷掉,要是要长久保存的话,那就在paint事件里面用鼠标按下和弹起记录的两个坐标用e.Graphics 画,画出来的矩形可以长久保存。

能不能麻烦写下具体代码,特别是换图的,我会加分的 谢谢!

#1


需要用到两层,原来的图放到底层,新画的图放上层透明,这样看起来就是完整的。待moseup时再新画的图合成到底图上。
另外,你的Graphics没有进行销毁

#2


仔细的看了一下楼主的代码,你的要求只是画一个矩形而已,不是动态的画,这样主要在mousedown里面记录一个开始坐标,在mouseup里面using(Graphics g = this.panel1.CreateGraphics())
{
//换图代码
}
这样就可以了,但是画出来的矩形框在遮挡后会被刷掉,要是要长久保存的话,那就在paint事件里面用鼠标按下和弹起记录的两个坐标用e.Graphics 画,画出来的矩形可以长久保存。

#3


该回复于2013-06-10 09:15:36被管理员删除

#4


可以参考这个文章来学习下的:
http://www.cnblogs.com/zhili/archive/2013/05/24/3096101.html
希望对你有帮助的

#5


就是做个鼠标拖动的选择框啊,我倒是做了的,拖动是个虚线框,好像c#有虚线框的绘制方法的。就是画那种可以反转颜色的矩形,鼠标移动的时候,搽除掉原来的,再重画一个

#6


这个我是做拓扑图,用来选择拓扑对象的时候用的。

#7


引用 1 楼 WM_JAWIN 的回复:
需要用到两层,原来的图放到底层,新画的图放上层透明,这样看起来就是完整的。待moseup时再新画的图合成到底图上。
另外,你的Graphics没有进行销毁

能不能麻烦写下具体代码,特别是换图的,我会加分的 谢谢!

#8


引用 2 楼 shenwenjie06 的回复:
仔细的看了一下楼主的代码,你的要求只是画一个矩形而已,不是动态的画,这样主要在mousedown里面记录一个开始坐标,在mouseup里面using(Graphics g = this.panel1.CreateGraphics())
{
//换图代码
}
这样就可以了,但是画出来的矩形框在遮挡后会被刷掉,要是要长久保存的话,那就在paint事件里面用鼠标按下和弹起记录的两个坐标用e.Graphics 画,画出来的矩形可以长久保存。

能不能麻烦写下具体代码,特别是换图的,我会加分的 谢谢!