Draw and move line segments in C#

example

This example lets the user draw and move line segments. It lets you perform three different operations depending on what is below the mouse.

  • When the mouse is over a segment, the cursor changes to a hand. Then you can then click and drag to move the segment.
  • When the mouse is over a segment’s end point, the cursor changes to an arrow. Then you can then click and drag to move the end point.
  • When the mouse is over nothing, you can click and drag to draw a new line segment.

The program handles all of these cases using MouseDown, MouseMove, and MouseUp events, but handling all of the possible combinations in one set of event handlers would be confusing. To make things easier to manage, the program uses separate MouseMove and MouseUp event handlers to perform its different tasks.

This post is divided into the following sections, which correspond to the program’s basic states.

Drawing

The program stores the coordinates of the segments’ end points in the lists Pt1 and Pt2.

// The points that make up the line segments.
private List Pt1 = new List<Point>();
private List Pt2 = new List<Point>();

While you’re drawing a new segment, the variable IsDrawing is true and the program stores the new segment’s end points in variables NewPt1 and NewPt2.

// Points for the new line.
private bool IsDrawing = false;
private Point NewPt1, NewPt2;

The Paint event handler simply loops through the Pt1 and Pt2 lists, drawing the segments and their end points. It then draws the new line (if you’re drawing one).

// Draw the lines.
private void picCanvas_Paint(object sender, PaintEventArgs e)
{
    // Draw the segments.
    for (int i = 0; i < Pt1.Count; i++)
    {
        // Draw the segment.
        e.Graphics.DrawLine(Pens.Blue, Pt1[i], Pt2[i]);
    }

    // Draw the end points.
    foreach (Point pt in Pt1)
    {
        Rectangle rect = new Rectangle(
            pt.X - object_radius, pt.Y - object_radius,
            2 * object_radius + 1, 2 * object_radius + 1);
        e.Graphics.FillEllipse(Brushes.White, rect);
        e.Graphics.DrawEllipse(Pens.Black, rect);
    }
    foreach (Point pt in Pt2)
    {
        Rectangle rect = new Rectangle(
            pt.X - object_radius, pt.Y - object_radius,
            2 * object_radius + 1, 2 * object_radius + 1);
        e.Graphics.FillEllipse(Brushes.White, rect);
        e.Graphics.DrawEllipse(Pens.Black, rect);
    }

    // If there's a new segment under constructions, draw it.
    if (IsDrawing)
    {
        e.Graphics.DrawLine(Pens.Red, NewPt1, NewPt2);
    }
}

Not Moving Anything

If the mouse moves while you’re not moving a segment or end point, the following event handler executes.

// The mouse is up. See whether we're over an end point or segment.
private void picCanvas_MouseMove_NotDown(object sender,
    MouseEventArgs e)
{
    Cursor new_cursor = Cursors.Cross;

    // See what we're over.
    Point hit_point;
    int segment_number;

    if (MouseIsOverEndpoint(e.Location, out segment_number,
        out hit_point))
            new_cursor = Cursors.Arrow;
    else if (MouseIsOverSegment(e.Location, out segment_number))
        new_cursor = Cursors.Hand;

    // Set the new cursor.
    if (picCanvas.Cursor != new_cursor)
        picCanvas.Cursor = new_cursor;
}

This code calls the MouseIsOverEndPoint and MouseIsOverSegment methods described later to see if the mouse is over anything interesting. It then displays the appropriate cursor. (Arrow if over an endpoint, hand if over a segment, and cross if over nothing.)

If you’re not moving anything and you press the mouse down, the following event handler executes.

// See what we're over and start doing whatever is appropriate.
private void picCanvas_MouseDown(object sender, MouseEventArgs e)
{
    // See what we're over.
    Point hit_point;
    int segment_number;

    if (MouseIsOverEndpoint(e.Location, out segment_number,
        out hit_point))
    {
        // Start moving this end point.
        picCanvas.MouseMove -= picCanvas_MouseMove_NotDown;
        picCanvas.MouseMove += picCanvas_MouseMove_MovingEndPoint;
        picCanvas.MouseUp += picCanvas_MouseUp_MovingEndPoint;

        // Remember the segment number.
        MovingSegment = segment_number;

        // See if we're moving the start end point.
        MovingStartEndPoint =
            (Pt1[segment_number].Equals(hit_point));

        // Remember the offset from the mouse to the point.
        OffsetX = hit_point.X - e.X;
        OffsetY = hit_point.Y - e.Y;
    }
    else if (MouseIsOverSegment(e.Location, out segment_number))
    {
        // Start moving this segment.
        picCanvas.MouseMove -= picCanvas_MouseMove_NotDown;
        picCanvas.MouseMove += picCanvas_MouseMove_MovingSegment;
        picCanvas.MouseUp += picCanvas_MouseUp_MovingSegment;

        // Remember the segment number.
        MovingSegment = segment_number;

        // Remember the offset from the mouse
        // to the segment's first point.
        OffsetX = Pt1[segment_number].X - e.X;
        OffsetY = Pt1[segment_number].Y - e.Y;
    }
    else
    {
        // Start drawing a new segment.
        picCanvas.MouseMove -= picCanvas_MouseMove_NotDown;
        picCanvas.MouseMove += picCanvas_MouseMove_Drawing;
        picCanvas.MouseUp += picCanvas_MouseUp_Drawing;

        IsDrawing = true;
        NewPt1 = new Point(e.X, e.Y);
        NewPt2 = new Point(e.X, e.Y);
    }
}

This method uses the MouseIsOverEndPoint and MouseIsOverSegment methods to see if the mouse is over anything interesting. If the mouse is over an end point or segment, the code starts moving that object.

Notice how the code uninstalls the picCanvas_MouseMove_NotDown event handler and installs new MouseMove and MouseUp event handlers for the operation it is starting.

The following code shows the MouseIsOverEndPoint and MouseIsOverSegment methods.

// See if the mouse is over an end point.
private bool MouseIsOverEndpoint(Point mouse_pt,
    out int segment_number, out Point hit_pt)
{
    for (int i = 0; i < Pt1.Count; i++ )
    {
        // Check the starting point.
        if (FindDistanceToPointSquared(mouse_pt, Pt1[i]) <
            over_dist_squared)
        {
            // We're over this point.
            segment_number = i;
            hit_pt = Pt1[i];
            return true;
        }

        // Check the end point.
        if (FindDistanceToPointSquared(mouse_pt, Pt2[i]) <
            over_dist_squared)
        {
            // We're over this point.
            segment_number = i;
            hit_pt = Pt2[i];
            return true;
        }
    }

    segment_number = -1;
    hit_pt = new Point(-1, -1);
    return false;
}

// See if the mouse is over a line segment.
private bool MouseIsOverSegment(Point mouse_pt,
    out int segment_number)
{
    for (int i = 0; i < Pt1.Count; i++)
    {
        // See if we're over the segment.
        PointF closest;
        if (FindDistanceToSegmentSquared(
            mouse_pt, Pt1[i], Pt2[i], out closest)
                < over_dist_squared)
        {
            // We're over this segment.
            segment_number = i;
            return true;
        }
    }

    segment_number = -1;
    return false;
}

These methods simply call the FindDistanceToPointSquared and FindDistanceToSegmentSquared methods. FindDistanceToPointSquared is trivial. For a description of how FindDistanceToSegmentSquared works, see the post Find the shortest distance between a point and a line segment in C#.

The program tests the square of the distance so it doesn’t need to calculate square roots, which are relatively slow. Note that x < y if and only if x2 < y2, so this test still determines whether an object is within the required distance of the mouse.

Drawing a New Segment

The following code shows the MouseMove and MouseUp event handlers that are active when you’re drawing a new segment.

// We're drawing a new segment.
private void picCanvas_MouseMove_Drawing(object sender,
    MouseEventArgs e)
{
    // Save the new point.
    NewPt2 = new Point(e.X, e.Y);

    // Redraw.
    picCanvas.Invalidate();
}

// Stop drawing.
private void picCanvas_MouseUp_Drawing(object sender,
    MouseEventArgs e)
{
    IsDrawing = false;

    // Reset the event handlers.
    picCanvas.MouseMove -= picCanvas_MouseMove_Drawing;
    picCanvas.MouseMove += picCanvas_MouseMove_NotDown;
    picCanvas.MouseUp -= picCanvas_MouseUp_Drawing;

    // Create the new segment.
    Pt1.Add(NewPt1);
    Pt2.Add(NewPt2);

    // Redraw.
    picCanvas.Invalidate();
}

When the mouse moves, the MouseMove event handler updates the value of NewPt2 to hold the mouse’s current position. It then invalidates the program’s PictureBox so its Paint event handler draws the current segments and the new one in progress.

When you release the mouse, the MouseUp event handler restores the “not moving anything” event handlers, adds the new segment’s points to the Pt1 and Pt2 lists, and invalidates the PictureBox to redraw.

Moving an End Point

The following code shows the MouseMove and MouseUp event handlers that are active when you’re moving an end point.

// We're moving an end point.
private void picCanvas_MouseMove_MovingEndPoint(object sender,
    MouseEventArgs e)
{
    // Move the point to its new location.
    if (MovingStartEndPoint)
        Pt1[MovingSegment] =
            new Point(e.X + OffsetX, e.Y + OffsetY);
    else
        Pt2[MovingSegment] =
            new Point(e.X + OffsetX, e.Y + OffsetY);

    // Redraw.
    picCanvas.Invalidate();
}

// Stop moving the end point.
private void picCanvas_MouseUp_MovingEndPoint(object sender,
    MouseEventArgs e)
{
    // Reset the event handlers.
    picCanvas.MouseMove += picCanvas_MouseMove_NotDown;
    picCanvas.MouseMove -= picCanvas_MouseMove_MovingEndPoint;
    picCanvas.MouseUp -= picCanvas_MouseUp_MovingEndPoint;

    // Redraw.
    picCanvas.Invalidate();
}

When the mouse moves, the MouseMove event handler updates the position of the point you are moving and then invalidates the PictureBox to make it redraw. The MouseUp event handler simply restores the “not moving anything” event handlers and redraws.

Moving a Line Segment

The following code shows the MouseMove and MouseUp event handlers that are active when you’re moving an end point.

// We're moving a segment.
private void picCanvas_MouseMove_MovingSegment(object sender,
    MouseEventArgs e)
{
    // See how far the first point will move.
    int new_x1 = e.X + OffsetX;
    int new_y1 = e.Y + OffsetY;

    int dx = new_x1 - Pt1[MovingSegment].X;
    int dy = new_y1 - Pt1[MovingSegment].Y;

    if (dx == 0 && dy == 0) return;

    // Move the segment to its new location.
    Pt1[MovingSegment] = new Point(new_x1, new_y1);
    Pt2[MovingSegment] = new Point(
        Pt2[MovingSegment].X + dx,
        Pt2[MovingSegment].Y + dy);

    // Redraw.
    picCanvas.Invalidate();
}

// Stop moving the segment.
private void picCanvas_MouseUp_MovingSegment(object sender,
    MouseEventArgs e)
{
    // Reset the event handlers.
    picCanvas.MouseMove += picCanvas_MouseMove_NotDown;
    picCanvas.MouseMove -= picCanvas_MouseMove_MovingSegment;
    picCanvas.MouseUp -= picCanvas_MouseUp_MovingSegment;

    // Redraw.
    picCanvas.Invalidate();
}

When the mouse moves, the MouseMove event handler updates the positions of the segment’s end points and redraws to show the new position. The MouseUp event handler simply restores the “not moving anything” event handlers and redraws.

What Next?

There are lots of other features you can add to a drawing program such as this one. You might want to add:

  • Other drawing tools such as polylines, polygons, scribbles, rectangles, ellipses, and so forth.
  • A different selection model so, for example, the user must select an object before seeing and moving its end points.
  • Grab handles that let the user resize a selected object. (You don’t need this if you’re only drawing line segments and you can move their end points.)
  • Snap-to-grid features.
  • Alignment tools such as Align Tops and Align Middles.
  • The ability to save and restore pictures.
  • The ability to remove objects and change their stacking order.
  • Shapes with different foreground and background colors.

I may get to some of these in future examples. (A better approach for those more flexible features would be to use classes to represent the objects in the drawing.)

Note also that building custom drawing tools is one of my favorite types of consulting, so if you want one built, email me.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in drawing, graphics and tagged , , , , , , , , , , , , . Bookmark the permalink.

75 Responses to Draw and move line segments in C#

  1. Goper says:

    Thank you for this. 🙂 But do you have a code to delete a specific line much appreciated…

    • RodStephens says:

      This example doesn’t have a selection model. In other words, you don’t select a segment and then manipulate it. You just click and drag a segment or an end point. Because you can’t select a segment, it’s not clear how you define deleting one.

      Probably creating a selection model where you can click and drag to select multiple segments, Shift+Click to add segments to the selection, and Ctrl+Click to toggle a segment’s selection is the best approach, but that would mean some major changes. I can think of a couple of alternatives.

      • You could have a radio button to let the user enter deletion mode. Then if you clicked on a segment, the program would delete it.
      • You could delete the segment if the user dragged it off of the form.
      • You could delete a segment if you dragged it onto a trashcan icon.

      Here’s an example that takes the last approach:

  2. Pingback: Draw, move, and delete line segments in C# - C# HelperC# Helper

  3. jayson says:

    can you post the whole source code please?

  4. jayson says:

    i cant find out if the cursor is in the bounds of the circle of an endpoint
    please help

  5. John says:

    Hi Rod,
    Excellent, I can draw my PCB tracks now.
    How can you get them to draw fullsize when printed, I have used
    e.Graphics.PageUnit = GraphicsUnit.Millimeter;
    but I dont know how to scale them properly or what i have to do to the lines
    any pointers would be helpful.

    Thank you

  6. Pingback: Print at full scale in C# - C# HelperC# Helper

  7. Sophie says:

    thank you so much for the beautiful tutorial!!

    but how do you create the extra mouse event handlers!? just make them up? or

    • RodStephens says:

      Do you mean the ones that are added and removed with += and -=? You can just type them in, but usually I use the Properties window to create an event handler at design time, copy its code, and remove the original from the control so the compiler doesn’t get all confused.

      Alternatively you can type something like:

          picCanvas.MouseMove +=

      Then IntelliSense will let you press Tab to create the new assignment statement and then Tab again to create an empty event handler. The assignment statement tends to be decorated with unnecessary extra stuff (like new FormClosingEventHandler(...)), but you can remove that if you don’t like it. (Or leave it if you do like it.)

  8. Keith Dudley says:

    Thanks you for your tutorials. I modified some of your tutorials on my end to fit my needs. Basically I have a triangle which has end points. I am try to drag end points to a new location. Could you assist me. Your tutorials are setup to move line segments. I want to be able to drag end points. Do you have a tutorial where you dragging endpoints instead.

    • RodStephens says:

      This example also lets you move end points. Just remove the code for moving segments. You may also need to modify the code that manages the triangle’s end points to keep track of them (if you haven’t already done that).

  9. Allen Kuo says:

    thank you for this example, Draw and move end points is very useful to me. And do you have the code (The ability to save and restore pictures). I really want to know how to implement the feature,Could you assist me?

  10. Alejandro says:

    hi Rod, thanks for you exercise, but have a problem, because when make zoom in and out dont cant resize the line, you can help me with this or have a solution, thanks

    • RodStephens says:

      Do you mean you wrote a program that lets you zoom and then you can’t resize the lines? Probably it’s because the drawing and mouse are working in different coordinates. For example, suppose you scale by a factor of 2. Then if the mouse is at (10, 30), it’s over the point (20, 60) in the drawing coordinates.

      You’ll need to use a transformation to convert the mouse’s position from screen coordinates in pixels into the drawing’s coordinates.

      • Alejandro says:

        i can zoom in/out in the lines, but in the momento of resize of line i can´t resize and the funcion that use for zoom/out is:

        – e.Graphics.ScaleTransform(zoom, zoom) this is for line and for image is:

        – image.Size = new Size(image.Width + 50, image.Height + 50);

  11. Charu says:

    hi how to select all lines , or rectangles drawn on picture box , i want them to move by selecting all.

    • RodStephens says:

      First create a list or collection to hold the selected objects. Replace all of the places where the program uses the selected object with code that loops through the collection.

      Then you need to change the selection model so the use can select multiple objects. For example, you could make Shift-Click add an object to the list. Or you could have click-and-drag select objects that are intersected by the selection rectangle.

      The idea is straightforward but the details can be tricky depending on which selection model you use.

  12. Marcos Vinicios says:

    Mr. Rod Stephens,

    I cant build a similar application following the steps that you wrote here.
    Could you post the whole code in C#? It will help me a lot to finish my final job in university.

    Thank you very much!
    Marcos.

    • RodStephens says:

      You can download the example program by clicking the Download button at the bottom of the post.

      All posts only include the most interesting code. There’s always other stuff that you need to make an example work, so you need to download the example to see the whole thing.

  13. Marino Liranzo says:

    Hello Mr. RodStephens,

    I would like to know how to snap at any point, ie the point does not belong to a grid system. Is that possible?.

    Greeting
    Marino Liranzo

    • RodStephens says:

      You could but you would have to define where it will snap.

      Or do you mean snap to existing points? You could loop through the existing points and see of any is close to the new point. If it is, then you can make the new point match the existing one.

  14. Marino Liranzo says:

    Hello Mr. RodStephens,
    I mean existing points. How to do it.
    Thank you.

    Greeting,
    Marino Liranzo

    • RodStephens says:

      As I said, just loop through the existing points, calculate the distance to the new point, and see if it is within some desired closeness. The following is off my head so it may not be perfect.

      foreach (PointF in points)
      {
          float dx = new_point.X - point.X;
          float dy = new_point.Y - point.Y;
          float dz = new_point.Z - point.Z;
          if (Math.Sqrt(dx * dx + dy * dy + dz * dz) < 5)
          {
              new_point = point;
              break;
          }
      }
  15. Marino Liranzo says:

    Mr. RodStephens

    Thank You.

    Marino Liranzo

  16. Rene Soto Villalta says:

    Hello RodStephens,

    Is amazing code, but there is not way to download the source.(no green button anymore)

    Kind regards and thanks for sharing ur knowlenge.

    • Rene Soto Villalta says:

      Sorry i found it, running the app I see always when I click on the panel a point is created(so no line for this point) singles points. there is a solution for that?

      Really thank you very much for this example.

      Kind regards.

      • RodStephens says:

        No problem. Just change the code that saves the new points so it doesn’t do that if the points are the same.

        // Create the new segment if the two points are differernt.
        if (NewPt1 != NewPt2)
        {
            Pt1.Add(NewPt1);
            Pt2.Add(NewPt2);
        }

        Or you could check the distance between the two points to make sure it is at least some minimum distance. That way you don’t make segments that are only one pixel long.

        // Create the new segment if the two points
        // are at least 5 pixels apart.
        int dx = NewPt1.X - NewPt2.X;
        int dy = NewPt1.Y - NewPt2.Y;
        if (dx * dx + dy * dy >= 5 * 5)
        {
            Pt1.Add(NewPt1);
            Pt2.Add(NewPt2);
        }
  17. Bjorn says:

    Hi,

    Nice demo!

    You seems to know a bit, or a lot, about WinForms graphics. I draw things with GraphicsPath to visualize paths between objects. Think of a warehouse with stations and trucks moving between the stations. Do you have any idea how I can draw a larger point, small circle, that traverses a GraphicsPath ? So you see that a truck moves from point A to point B. At the moment the paths are just 2-3 lines.

    I know this is simple in WPF, but we use WinForms.

    Cheers
    Bjorn

    • RodStephens says:

      Hi Bjorn,

      In some ways, I think this is easier in Windows Forms. In WPF you can make an animation that does this automatically, but it’s harder to set up. In Windows Forms, you need to do it yourself (which can be hard if you want fancy smoothing, interpolation, acceleration, etc.), but at least the steps for a basic animation are easy to understand.

      In Windows Forms, you need to create a timer to move the object. When the timer fires, you move the point a little bit. The hardest part is keeping track of the object’s position along its path.

      In your case, I would use the GraphicsPath object’s Flatten method to convert it into a sequence of line segments. Then make the object follow those. You still need to keep track of where it is on each segment. For example, if you want to move 5 pixels and it has 3 pixels left on the current segment, then you need to move it 2 pixels onto the next segment.

      This example does something similar:

      Animate the Tower of Hanoi problem in C#

      Let me know if you get stuck and I’ll try to help.

  18. Jaydip says:

    Hi. I want to draw arrow between two datagrid items match. and also need ability to update that arrow from datagrid one item to another datagrid another item. so can you please let me know how can i draw it ?

    • RodStephens says:

      Sorry, but I think that’s going to be hard. The DataGrid is a control so it draws itself and it will probably be very hard to draw on top of it. I’m sure you could draw the lines if you draw all of the data instead of using the DataGrid to display it, but that would be additional work.

  19. Marino Liranzo says:

    Hi Mr. Stephens Rod,
    It is a fabulous job that shows the initiates to the enthusiast of the coding programming so important.

    I would appreciate a little help with the following concern

    I have implemented a version of your code and something I would like to do is that when I want to draw lines, the end point or the line will not move, only the line will be drawn.

    Thank you in advance

    Atte. Marino Liranzo

  20. Marino Liranzo says:

    Hello Mr. Rod Stephens,
    I have two List Pt1 and List Pt2 to create lines in a picturebox, the points Pt1 and Pt2 are captured from the points that form the intersection of a line grid.
    I would like that when the grid is updated, the points Pt1 and Pt2 adopt the new values of the intersections of the lines of the grid. I have try with the following code; but it does not work for me.

    public void pegarPuntosaEjes(List listCoo, List lisPt1)
    {
        // Mover los puntos Pt1 a su  nueva localizacion
        elDibujo.Pt1 = new List();
        for (int i = 0; i < lisPt1.Count; i++) {
            for (int j = 0; j < listCoo.Count; j++) {
                if(lisPt1[i].Equals(listCoo[j])){
                    PointF nPto1 = new PointF(listCoo[j].X, listCoo[j].Y);
                    elDibujo.Pt1.Add(nPto1);
                }
            }
        }
    }

    I would appreciate your help.

    • RodStephens says:

      I don’t think I understand. Are you trying to draw the grid? What result do you see?

      Where is the code that actually does the drawing? It looks like you’re making a list of points that are in both lists lisPt1 and listCoo, but I don’t see the code that draws them. Is it in a Paint event handler?

  21. chandran says:

    Hi,
    Thanks for the code.
    Is it possible to do the same for rectangles also?
    I need to draw, move, resize and delete the rectangles.

  22. meriem says:

    hello, thanks for your code it exactly what i need in my application. I also need to change the color of the lignes with a button click event, but when i do that every single ligne i draw before change it color automaticly, i tried different codes to handel this but it does’t work. i hope you can help me with this.

    • RodStephens says:

      The way the program works is to draw the lines in the Paint event handler. The first loop makes every line red.

      If you want different colors, you’ll need some data structure to store each line’s color. For example, you could use a list of colors where the k-th entry corresponds to the k-th line. When the user has a line selected, you can let a context menu or something change its color. Then refresh the PictureBox to redraw with the new colors.

      • meriem says:

        Actuly, I need to draw lines in diffrent colors depending of the color of the button i clicked, in the same pictureBox,
        And what you saying is how i could change the color of the lines after drawing it.
        I tried to make a pen and change it color in the click even of the button but when i click all the lines i drow before change the color, and it not what i want. i think all of this hapen because i m drawing with the same points and when i switch the color it applys on all of the list points. i tried to create other lists but it still don’t work,

        • RodStephens says:

          The example as it is uses a single color in the Paint event handler. You need to store a different color for each segment. Probably what you should do it make a class to hold drawing properties such as color, line width, dash pattern, etc. Let the user select those properties (either by using a button or a set of other tools like in a toolbox). Then when you draw a new segment, apply the current settings to it. You can decide whether you want to let the user change a segment’s settings later.

  23. meriem says:

    it doesn’t work or i m doing it wrong, please help me i realy need to do this.

    • RodStephens says:

      Be sure you download the example program and don’t just copy and paste the code shown on the page. The example includes things like event handlers that are defined at design time and that can’t appear on the web page.

  24. Marino Liranzo says:

    Hi Mr. Rod Stephens,

    I have been trying without any results to implement the line drawing from your code in the picCanvas.Mouse_Move + = Mouse_Move_NoDown event, that is, draw with the mouse button above.

    I would appreciate a help in this regard.
    Atte. Marino Liranzo

    • RodStephens says:

      Basically the program registers and unregisters the event handlers depending on what is happening at a given moment. You should download the example to see all of the details.

  25. Marino Liranzo says:

    Hello Mr. Stephens Rod,
    I have tried multiple ways and I have not been able to get it. You could suggest me how to modify your code to be able to draw lines with the raised mouse button.
    Atte. Marino Liranzo

    • RodStephens says:

      I don’t know how you can move line segments with the mouse button raised. You need to do something to tell the program that you’re moving a line and not doing something else like drawing a new one or not doing anything at all.

      • Marino Liranzo says:

        The idea is that the piece of code that captures the point NewPt1 is in the event MouseDown and NewPt2 is captured with a MouseClick event or a picCanva.Click, is the approach I raise.
        I am looking for the lines to be drawn as the AutoCad does.

        • RodStephens says:

          I don’t know AutoCad, but I think you need to look at the picCanvas_MouseUp_Drawing event handler. That is the one that determines where the new line’s second end point is placed.

          If you want to set that end point with a click instead of a mouse up, change picCanvas_MouseUp_Drawing to a Click or MouseClick event handler.

          You should probably change its name. Then change the lines that install and uninstall it to use the new name. For example:

              picCanvas.MouseUp += picCanvas_MouseUp_Drawing;
              ...
              picCanvas.MouseUp -= picCanvas_MouseUp_Drawing;

          Should become something like this:

              picCanvas.MouseClick += picCanvas_MouseClick_Drawing;
              ...
              picCanvas.MouseClick -= picCanvas_MouseClick_Drawing;
  26. Marcelo M Caparoz says:

    Hi Mrs
    Nice work!

    I put the points segments on a DataGridView
    And when a click on a EndPoint or Segment, its highlight the DatagridView Row

    DatagridView1.Rows[segment_number].Selected = true;
    DatagridView1.CurrentCell = DatagridView1.Rows[segment_number].Cells[0];

    This Works

    But, how to invert it?
    Parsing the segment number, its higlight or change color of line segment or endpoint?

    Thanks

    • RodStephens says:

      You need a way to identify specific segments. Probably at this point you should make a Segment class. Then you can give it an IsSelected property and draw it differently if it is selected.

      I would also give it a Draw method and male it draw itself. At that point, you could also give the lines Color, Thickness, and other properties so they can have different appearances.

  27. karthick says:

    Hi, I write program for Diagram Editor(Simulation Process). I need to drag and drop the image in canvas panel and connect object with lines. I need to set anchor in each object corner Then when i click the corner(for ex: right edge anchor) with mouse dragging line draw automatically. i don’t know how to code it. please send sample code or tips for me.

  28. David Sesma Cano says:

    Hi Rod,
    So nice code, thanks so much, I try to use in my source, but I have a great problem.
    I have several panels, in each one I have a PictureBox.
    1st: The panels could change Size and the Pbox adapt the Size to show the image in ZoomMode
    2nd: I could do Zoom out and in over Each PictureBox, and the Image inside show as ZoomMode but with different Location (that’s means Image is greater and Location decrease to show center image in the picturebox center, or Image is lower and Location increase to center Image)

    My problem is to redifine the new Points in both cases

    Any Idea?

  29. rock says:

    Hello , i need help that …
    i want create rows and columns which should me movable and resize able in richtextbox adding multiple rows and columns through button thanks

  30. javed Iqbal says:

    hello sir nice to meet you .. i am working on a project like ms word software i get many solutions of my problems from your belong but facing some additional problem how to create table (row cell and columns cell) grammatically which resize by mouse and also be delete if use any button thanks waiting for your reply

    • RodStephens says:

      I’m not sure exactly what you want. Do you mean you want to place a table in the word processor that you’re building? If you’re using C#, then you should probably try to use an existing control such as a grid or ListView. Allowing the user to move and resize it would be hard, but building one yourself would be harder.

  31. RONY says:

    hello sir thanks for giving use information to the programmers who are interested in c# programming language. i have issue to save the content of richtextbox or textbox .in pdf format using manually size of page like creating 7*3 (height and width) pdf file kindly if u have code i need little help thanks

  32. laibia says:

    hello sir how to get text box in centimeters at run time while asking width and height also in centimeters in c# wpf

    • RodStephens says:

      WPF measures distances in logical pixels, which are normally 96 per inch. There are 2.54 cm per inch. So to get a control’s width or height, use:

      cm_width = pix_width / 96 * 2.54
      cm_height = pix_height / 96 * 2.54

      In WPF you should probably use the control’s ActualWidth and ActualHeight properties to get the control’s dimensions.

      Note that the exact size of the pixels on your computer may vary slightly depending on your monitor.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.