C#鼠标绘图程序的问题
做了一个绘图程序在鼠标移动时候能画出线来,但是为了使鼠标的移动不会产生很多条线,只有一条线跟着鼠标在画。在MouseMove事件中画线之前加了这个方法
graphics.clear()
这样解决了留下鼠标轨迹的问题,但是画第2条线的时候第一条线也会被清除掉,请问怎么解决这问题 --------------------编程问答-------------------- 第一种方法:画第二条线之前,使用背景色重画第一条线。(不推荐)
第二种方法:在类中定义记录需要画线的数据的成员,在MouseMove消息中,更新数据,执行Invalidate();在Paint事件处理方法中,根据数据画线。 --------------------编程问答-------------------- 我也想知道,顶了 --------------------编程问答--------------------
第二种方法能说清楚点吗?不好意思我是菜鸟~~最好给个代码例子 --------------------编程问答--------------------
--------------------编程问答-------------------- 画线可以使用ControlPaint.DrawReversibleLine方法,就不会出现很多线了.
class XForm:Form
{
private Point pt1,pt2;
...
public Form()
{
pt1=new Point(0,0);
pt2=new Point(0,0);
}
...
private void MouseMove(object sender,MouseEventArgs e)
{
pt2.X=e.X;
pt2.Y=e.Y;
Invalidate();
}
private void MouseDown(object sender,MouseEventArgs e)
{
pt1.X=e.X;
pt1.Y=e.Y;
}
private void Paint(object sender,PaintEventArgs e)
{
e.Graphics.DrawLine(Pens.Black,pt1,pt2);
}
...
}
先用它画一个线,记录坐标,移动时,先用它利用记录的坐标画一次来擦出原来的线,在用新坐标画.
mouseDown:
ControlPaint.DrawReversibleLine(...);
//记录坐标...
mouseMove:
ControlPaint.DrawReversibleLine(记录的坐标);
ControlPaint.DrawReversibleLine(新坐标);
//记录新坐标...
mouseUP:
ControlPaint.DrawReversibleLine(记录的坐标);
ControlPaint.DrawReversibleLine(新坐标);
--------------------编程问答-------------------- 楼主可以做个参考:
--------------------编程问答-------------------- private void DrawToolBar_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)
public partial class DrawLine : Form
{
class LineObj
{
private Point m_start;
private Point m_end;
public LineObj(Point start, Point end)
{
this.m_start = start;
this.m_end = end;
}
public void Draw(Graphics g, Pen pen)
{
g.DrawLine(pen, m_start, m_end);
}
}
private Point m_startPoint = Point.Empty;
List<LineObj> lineList = new List<LineObj>();
public DrawLine()
{
InitializeComponent();
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
}
private void drawLine(Graphics g, Point startPoint, Point endPoint)
{
BufferedGraphicsContext context = BufferedGraphicsManager.Current;
BufferedGraphics bg = context.Allocate(g, this.ClientRectangle);
bg.Graphics.Clear(this.BackColor);
foreach (LineObj line in this.lineList)
{
line.Draw(bg.Graphics, SystemPens.ControlText);
}
bg.Graphics.DrawLine(SystemPens.ControlText, startPoint, endPoint);
bg.Render();
bg.Dispose();
bg = null;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
foreach (LineObj line in this.lineList)
{
line.Draw(e.Graphics, SystemPens.ControlText);
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
this.m_startPoint = new Point(e.X, e.Y);
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (e.Button == MouseButtons.Left)
{
this.drawLine(this.CreateGraphics(), this.m_startPoint, new Point(e.X, e.Y));
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
LineObj line = new LineObj(this.m_startPoint, e.Location);
this.lineList.Add(line);
}
}
{
foreach(ToolBarButton btnToolBar in DrawToolBar.Buttons)
{
btnToolBar.Pushed = false;
}
e.Button.Pushed = true;
textBox1.Text=e.Button.Text;
}
private void pictureBox1_MouseDown_1(object sender, System.Windows.Forms.MouseEventArgs e)
{
int X=e.X; //当前X坐标
int Y=e.Y; //当前Y坐标
if(!down)
{
X1=X;Y1=Y;
down=true;
}
}
private void pictureBox1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if(down)
{
int X=e.X; //当前X坐标
int Y=e.Y; //当前Y坐标
X2=X;Y2=Y;
Graphics g=this.pictureBox1.CreateGraphics();//创建一个Graphics对象
Pen mypen=new Pen(btnPenColor.BackColor); //创建一个画笔
Draw objDraw=new Draw();
g.Clear(pictureBox1.BackColor);//清除鼠标轨迹
switch(textBox1.Text)
{
case "矩形":
objDraw.DrawRectangle(g,mypen,X1,Y1,X2,Y2);
break;
case "直线":
objDraw.DrawLine(g,mypen,X1,Y1,X2,Y2);
break;
case "圆":
objDraw.DrawEllipse(g,mypen,X1,Y1,X2,Y2);
break;
default:
break;
}
g.Dispose();
}
}
private void pictureBox1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
down=false;
}
这是我的部分代码,画第2个图形时候,第1次画的会被清除,谁能帮改下 --------------------编程问答-------------------- g.Clear(pictureBox1.BackColor);//清除鼠标轨迹
-------------------
这样肯定会把前面所绘制的清除 --------------------编程问答--------------------
我知道啊~~但是不这样的话鼠标轨迹一直留在屏幕上 --------------------编程问答-------------------- 你需要另外一个变量,用来记录上一次发生MouseMove事件时的坐标,并在绘制新图形之前,使用背景色擦除上一次绘制的图形。 --------------------编程问答-------------------- 意思是在MouseUp()时候用变量把两个点的坐标保存起来,在MouseMove事件中g.Clear(pictureBox1.BackColor);
之后再把上次的图给绘出来?
用什么变量能保存呢?普通的变量只能保存一个图的,如果有多个图怎么办? --------------------编程问答-------------------- 两个点不会用两个Point类型的变量保存么?
g.Clear(pictureBox1.BackColor); 执行了这个就什么都没有了。
在你创建画笔的地方,再加:
Pen eraserPen=new Pen(pictureBox1.BackColor);
在下面你绘制图形的语句前面,再使用这个画笔在上次画的地方画一次,就可以擦除了。
多个图?你这个本来无论何时,都只是在绘制一种图形。 --------------------编程问答-------------------- 我这儿写了部分鼠标绘图的代码,lz可参考一下。
http://blog.csdn.net/wzuomin/archive/2006/12/13/1441007.aspx --------------------编程问答--------------------
学习楼上的...顶. --------------------编程问答--------------------
我尝试过好几种方法,还是调用API函数效果最好!
建议你试试! --------------------编程问答-------------------- 用到这两个API函数:
[DllImport("gdi32.dll")]
public static extern bool MoveToEx(IntPtr hdc,
int x, int y, ref LPPOINT lpPoint);
[DllImport("gdi32.dll")]
public static extern bool LineTo(IntPtr hdc,
int x, int y);
然后在鼠标移动过程中不停的MoveToEx,LineTo,就可以了。这么做不会产生闪烁,而且速度快! --------------------编程问答--------------------
你的两种方法都会产生闪烁,不好。
还是调用API函数画比较好! --------------------编程问答-------------------- http://download.csdn.net/source/504610 这边有代码,是画在窗体上的,可以参考一下
补充:.NET技术 , C#