如何使用MouseMove事件绘制单行

时间:2010-09-15 01:50:57

标签: c# winforms events graphics gdi

我正在尝试使用OnMouseMove()事件绘制一行。我的问题是每次我移动鼠标都会留下痕迹。我尝试使用刷新方法,但当我停止移动鼠标时,线条消失了。我不希望绘制线OnPaint();,只想绘制它OnMouseMove()

编辑:我正在使用透明面板(cp.ExStyle | = 0x20;),因此我无法使用graphics.Clear()BackColor()

这是没有Refresh()的示例图片:

alt text

这是我的代码:

private void panel1_MouseMove(object sender, MouseEventArgs e)
{  
   Graphics g = panel1.CreateGraphics();

   g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
   using (var p = new Pen(Color.Black, 3))
   {
      p.StartCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
      p.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;

      g.DrawLine(p, st, e.Location);
   }
   Thread.Sleep(30);
   Invalidate();
   //this.Refresh();

   g.Dispose();
}

此致

5 个答案:

答案 0 :(得分:3)

以下适用于我。基本上跟踪绘制的最后一条线并使用面板的背景颜色绘制它(给出清除它的效果)。

   public partial class Form1 : Form
   {
      public Form1()
      {
         InitializeComponent();
      }

      private const int PEN_WIDTH = 3;
      private const LineCap START_CAP = LineCap.ArrowAnchor;
      private const LineCap END_CAP = LineCap.ArrowAnchor;
      Point mAnchorPoint = new Point(10, 10);
      Point mPreviousPoint = Point.Empty;

      private void panel1_MouseMove(object sender, MouseEventArgs e)
      {
         using (Graphics g = panel1.CreateGraphics())
         {
            // Clear last line drawn
            using (Pen clear_pen = new Pen(panel1.BackColor, PEN_WIDTH))
            {
               clear_pen.StartCap = START_CAP;
               clear_pen.EndCap = END_CAP;
               g.DrawLine(clear_pen, mAnchorPoint, mPreviousPoint);
            }

            // Update previous point
            mPreviousPoint = e.Location;

            // Draw the new line
            using (Pen draw_pen = new Pen(Color.Black, PEN_WIDTH))
            {
               draw_pen.StartCap = START_CAP;
               draw_pen.EndCap = END_CAP;
               g.DrawLine(draw_pen, mAnchorPoint, e.Location);
            }
         }
      }
   }

如果面板的背景颜色设置为透明,则需要将panel1.BackColor更改为panel1.Parent.BackColor

如果透明面板不起作用,您可以使用DrawReversibleLine功能(虽然这不允许更改线条的颜色或粗细,但即使是绘图/删除也不应该有问题面板是透明的:

  Point mAnchorPoint = new Point(200, 200);
  Point mPreviousPoint = Point.Empty;

  private void panel1_MouseMove(object sender, MouseEventArgs e)
  {
     if (mPreviousPoint != Point.Empty)
     {
        // Clear last line drawn
        ControlPaint.DrawReversibleLine(PointToScreen(mAnchorPoint), PointToScreen(mPreviousPoint), Color.Pink);
     }

     // Update previous point
     mPreviousPoint = e.Location;
     mPreviousPoint.Offset(myPanel1.Location);

     // Draw the new line
     ControlPaint.DrawReversibleLine(PointToScreen(mAnchorPoint), PointToScreen(mPreviousPoint), Color.Pink);
  }

答案 1 :(得分:3)

在C#中使用鼠标绘制线条的另一种简单方法:

public partial class Form1 : Form
{
    Options_c o = new Options_c();

    public Form1()
    {
        InitializeComponent();
    }

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        o.Allow = false;

    }

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        o.Allow = true;
        o.X = e.X;
        o.Y = e.Y;
    }

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        if (o.Allow == true)
        {
            Graphics g = pictureBox1.CreateGraphics();
            Pen p1 = new Pen(o.color, 5);
            g.DrawLine(p1, o.X,o.Y, e.X, e.Y);
            o.X = e.X;
            o.Y = e.Y;
        }
    }
}

class Options_c
{
    public Boolean Allow = false;
    public Int32 X;
    public Int32 Y;
    public Color color = Color.Bisque;
}

答案 2 :(得分:0)

线条消失的问题是,当重新绘制面板时,不会重新绘制线条。您真正需要的是在鼠标移过面板时更新线段的终点并使面板无效。当然,这意味着您处理面板上的Paint事件。

这里的代码,没有事件处理程序注册:

Point endPoint;

private void panel1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

    using (var p = new Pen(Color.Black, 3))
    {
        p.StartCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
        p.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;

        g.DrawLine(p, st, endPoint);
    }

    Thread.Sleep(30);
}

private void panel1_MouseMove(object sender, MouseEventArgs e)
{
    endPoint = e.Location;
    panel1.Invalidate();
}

答案 3 :(得分:0)

g.DrawLine(p, st, e.Location); 

放:

st = e.Location;

这样可以解决问题吗?

答案 4 :(得分:0)

  好的,我明白了!如果你必须在两个geopoint之间画一条线   在这两个位置上的位置,然后你必须使用   这个形状的覆盖类...我的代码是:

主活动中的

也写下此代码:

          public void onCreate(Bundle savedInstanceState)
        {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

         mapView = (MapView) findViewById(R.id.mapView1);            
         mapView.setBuiltInZoomControls(true);
        mapOverlays = mapView.getOverlays();//it get the mapview all overlays...

         mc = mapView.getController();
        mc.setZoom(13);
        GeoPoint p = new GeoPoint(34159000,73220000);//starting point Abbottabad    
        GeoPoint p1 = new GeoPoint(41159000,43220000);//starting point Abbottabad   
         List<Overlay> mapOverlays2 ;
            mapOverlays2 = mapView.getOverlays();
             projection = mapView.getProjection();  
             myoverlay = new MarkerOverlay(p,p1);
            mapOverlays2.add(myoverlay);//*/

     }


    class MarkerOverlay extends Overlay
    { 
               GeoPoint p,p1;
       private GeoPoint pa;
       public MarkerOverlay(GeoPoint p,GeoPoint p1)
         {  
                     this.p = p;
             this.p1=p1;
            Toast.makeText(GoogleMapShowActivity.this, "point value is "+p +"-->"+p1, Toast.LENGTH_LONG).show();

         }

         public void draw(Canvas canvas, MapView mapView,boolean shadow)//), long when)
         {
            super.draw(canvas, mapView, shadow);                   

            Paint mPaint = new Paint(); 
         mPaint.setDither(true);    
         mPaint.setColor(Color.RED);    
         mPaint.setStyle(Paint.Style.FILL_AND_STROKE);  
         mPaint.setStrokeJoin(Paint.Join.ROUND);    
         mPaint.setStrokeCap(Paint.Cap.ROUND);  
         mPaint.setStrokeWidth(4); 

         GeoPoint gP1 = new GeoPoint(p.getLatitudeE6(),p.getLongitudeE6());//starting point Abbottabad  
         GeoPoint gP2 = new GeoPoint(p1.getLatitudeE6(),p1.getLongitudeE6());//(33695043,73050000);//End point Islamabad            


         Point p1 = new Point();    
         Point p2 = new Point();
         Path path1 = new Path();               
         projection.toPixels(gP1, p1);  //changing the latitude into the screen pixels.
         projection.toPixels(gP2, p2);  
        path1.moveTo(p1.x, p1.y);//Moving to Abbottabad location
         path1.lineTo(p2.x,p2.y);//Path till Islamabad  
      canvas.drawPath(path1, mPaint);//Actually drawing the path from Abbottabad to Islamabad

         }

         //--------------------------//
        public boolean onTouchEvent(MotionEvent event, MapView mapView) 
          {
            location_touch++;//this is called two times before executing other codes in thsi method(), 
            // Toast.makeText(GoogleMapShowActivity.this, "this is mmmm"+location_touch, Toast.LENGTH_LONG).show();
               if (event.getAction() == 1)
               {

                 // Toast.makeText(GoogleMapShowActivity.this, "this is me ..."+location_touch, Toast.LENGTH_LONG).show();
                  GeoPoint p = mapView.getProjection().fromPixels((int) event.getX(), (int) event.getY());

                           if((location_touch%2)!=0)
                            {
                                location_touch=0;
                                Toast.makeText(GoogleMapShowActivity.this, "VALUE 2..."+location_touch+"gp is "+p+",,"+p1, Toast.LENGTH_LONG).show();
                                mapView.getOverlays().add(new MarkerOverlay(p,pa));
                                mapView.invalidate();

                            }
                           else //if((location_touch==0 ))
                            {
                              pa=p;
                                Toast.makeText(GoogleMapShowActivity.this, "VALUE 1.."+location_touch+",,,"+p1, Toast.LENGTH_LONG).show();
                                location_touch++;


                            }