3

I want to create an application which the user is able to manipulate the line he draw. Something like Deleting the line or Selecting it. How should I do that?

Thanks in advance


I managed to do it using a hard coded rectangle. But I don't still have an idea how to do it using the drawLine() Can I use drawPath to do the hit test?

Here is the code:

private bool selectGraph = false;
private Rectangle myrec = new Rectangle(50, 50, 100, 100);
private Graphics g;

private void panel1_Paint(object sender, PaintEventArgs e)
    {
        SolidBrush sb = new SolidBrush(Color.Blue);
        Pen p = new Pen(Color.Blue, 5);

        e.Graphics.DrawRectangle(p, myrec);
        e.Graphics.FillRectangle(sb, myrec);
    }

    private void panel1_MouseUp(object sender, MouseEventArgs e)
    {
        Point mPT = new Point(e.X, e.Y);

        if (e.Button == MouseButtons.Left)
        {
            if (myrec.Contains(mPT))
            {
                selectGraph = true;
                button1.Enabled = true;
            }
            else
            {
                selectGraph = false;
                button1.Enabled = false;
            }
        }
        Invalidate();
    }
TheCloudlessSky
  • 18,608
  • 15
  • 75
  • 116
Rye
  • 2,273
  • 9
  • 34
  • 43
  • Crap there's a visualbasic powerpack tools. – Rye Aug 31 '10 at 04:51
  • Please, oh please, get rid of that `g = panel1.CreateGraphics();` line! You're already in the `Paint` event hander. The `PaintEventArgs` has a property called `Graphics` that you use to paint to. Your application will be slow and extremely buggy if you use your current way. :) – TheCloudlessSky Aug 31 '10 at 11:37
  • @TheClodlessSky yes, I already erased that kind of approach! I'm kinda new to GDI thats why lol. Thanks TCS :) – Rye Aug 31 '10 at 13:25

2 Answers2

2

Well you could start with something like a simple Line class:

public class Line
{
    public Point Start { get; set; }
    public Point End { get; set; }
}

Then you could have your form:

private Line Line = new Line();

protected override void OnPaint(PaintEventArgs e)
{
    e.Graphics.DrawLine(Pens.Red, this.Line.Start, this.Line.End);
}

protected override void OnMouseMove(MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        this.Line.Start = e.Location;
        this.Refresh();
    }
    else if (e.Button == MouseButtons.Right)
    {
        this.Line.End = e.Location;
        this.Refresh();
    }
}

So basically then they could delete the this.Line maybe on "MiddleButton" click or something. This should be enough to get you started.

I've created a sample that shows how this can be done. Set some break points and see how things are done.

TheCloudlessSky
  • 18,608
  • 15
  • 75
  • 116
  • This is on mouse move event. What I want is that when the line is already on the paint event I can drag, select and delete it. Similar to drag and drop of visual studio user control. When the user adds for example a button he can move it around the form. – Rye Aug 30 '10 at 00:15
  • @Rye - Ok, but what I've provided for you is the foundation for you to get started. "Drag" is basically "MouseMove" when a button is pressed. If you want drag to move the line, you'll need to offset both the `Start` and `End` points. If you want to "delete" it, you can then set Line to NULL. – TheCloudlessSky Aug 30 '10 at 00:24
  • Yes Yes, but my main problem is selecting the line. – Rye Aug 30 '10 at 06:59
  • 1
    @Rye - *you* have to implement the selecting of the line. For example, "OnClick" could take `e.Location` and see if it's within 10px of the line, if so "then select the line" (you could set Selected=true on the Line object), then redraw. `OnPaint` could say `if Line is selected, draw it red, otherwise, black`. That should be more than enough to get you started. – TheCloudlessSky Aug 30 '10 at 12:15
  • Ah, that means It is click-able using the graphics object position. Good idea. – Rye Aug 30 '10 at 23:41
  • @Rye - yes. You do all your logic of moving, etc in the Mouse event handlers, and then call `Refresh()` to re-draw the control. Then use `OnPaint` to do the handling. There's no concept of "select and object", you need to create this idea yourself. – TheCloudlessSky Aug 31 '10 at 11:34
  • @TCS This is very useful! Thanks for this one. You're comments are also great, makes me understand the code quickly. :) – Rye Aug 31 '10 at 23:15
  • Hey @TCS just want to thank you for the sample program that you gave me. that helps me a lot. Your the best :) Cheers! – Rye Sep 22 '10 at 00:50
  • @TheCloudlessSky Hello, I am trying to solve the same problem and i tried to download the sample(from the sendspace link). However it seems to download some junk file. Any Chance you still have the sample. – Win Coder Jun 27 '13 at 15:22
  • @WinCoder - Hmm... it seems SendSpace changed the link to something else. I don't have the sample. But I've whipped together a sample Gist for you: https://gist.github.com/TheCloudlessSky/5880943 – TheCloudlessSky Jun 27 '13 at 22:26
0

There is no easy one line solution for this. You would have to program this yourself.

You have to keep track of every object you have drawn. In the onmousedown event you have to find out if the mouse has clicked on or near an object you want to move/delete by comparing coordinates. Then you need to draw some visual guide that the line is 'selected'. Deleting is now quite easy by removing the object from the collection.

For drag and drop you have to do something similar by changing the coordinates of the object according to the mouse move.

Ikke
  • 99,403
  • 23
  • 97
  • 120