3

I'm trying to draw a single line using OnMouseMove() event. My Problem is that everytime I move the mouse It leaves a trail. I tried to use the refresh method, but when I stop moving the mouse the line is gone. I don't want the line to be drawn OnPaint();, Just want to draw it OnMouseMove().

EDIT: I'm using a transparent panel(cp.ExStyle |= 0x20;), so I cant use the graphics.Clear() and BackColor()

Here's a Sample Image without the Refresh():

alt text

Here's my code:

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();
}

Regards

Rye
  • 2,273
  • 9
  • 34
  • 43
  • 1
    You can't make this work. Fix: http://social.msdn.microsoft.com/forums/en-US/winforms/thread/3087655c-bd50-4408-9c55-dd179e442675/ – Hans Passant Sep 15 '10 at 03:23

5 Answers5

3

Another simple way to draw a line with mouse in 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;
}
KatieK
  • 13,586
  • 17
  • 76
  • 90
AiviS
  • 31
  • 1
3

The following works for me. Basically keep track of the last line drawn and draw over it with the background color of the panel (gives the effect of clearing it).

   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);
            }
         }
      }
   }

If you panel's background color is set to Transparent, you will need to change panel1.BackColor to panel1.Parent.BackColor

If the Transparent Panel is not working, you could use the DrawReversibleLine function (although this doesn't allow the color or thickness of the line to be changed, it should have no issues with drawing/erasing even if the panel is Transparent:

  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);
  }
SwDevMan81
  • 48,814
  • 22
  • 151
  • 184
0

OKaie, i got it! If you have to draw a line between two geopoint location on tocuhing these two location, then u have to use the overlay class in this shape... MY CODE IS :

in Main activity write this code also:

          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++;


                            }
Pir Fahim Shah
  • 10,505
  • 1
  • 82
  • 81
0

The problem with the line disappearing is that when the panel is repainted, the line is not redrawn. What you really need is to update the end-point of the line-segment when the mouse is moved across the panel and to invalidate the panel. Of course, this will mean that you do handle the Paint event on the panel.

Code here, without the event-handler registration:

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();
}
Ani
  • 111,048
  • 26
  • 262
  • 307
  • the g.Clear() is good. But i forgot to include there that I override a panel user control with CreateParams. So the panel is set to transparent. that's why I cant use the g.Clear(); – Rye Sep 15 '10 at 02:16
  • @Rye: Alright. But why can't you handle the `Paint` event? That's the easiest way. – Ani Sep 15 '10 at 02:20
  • @Rye: Can you explain what that means? – Ani Sep 15 '10 at 02:24
  • I have a transparent Panel. It is positioned above an image(e.g picturebox), This image contains line drawings. I just want to measure the drawings using the drawline on `MouseMove()` event. – Rye Sep 15 '10 at 02:50
0

After

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

put:

st = e.Location;

Does that fix the problem?

BoltBait
  • 11,361
  • 9
  • 58
  • 87
  • Nope, It just creates new line. – Rye Sep 15 '10 at 02:18
  • Oh, right. I thought you were trying to draw like a pencil. I see now that you want to have a single starting place and be able to move the end point around having it redraw only a single line between the start point and the new end point. – BoltBait Sep 15 '10 at 02:22