1

I have the following problem: I want to create a Usecasehelper with removable lines.

if (lineRadioButton.Checked)
{
    if (xpos == -1)
    {
        xpos = e.X;
        ypos = e.Y;
    }
    else
    {
        gs.DrawLine(l, new Point(xpos, ypos), new Point(e.X, e.Y));
        xpos = -1;
        ypos = -1;
    }
}

I want to create an option for a line selection to remove but I dont know how to do that.
When I have checked line & select I want to get an option to remove my linecreation.

The app i want to create

Kilazur
  • 3,089
  • 1
  • 22
  • 48
Stefan Gies
  • 318
  • 4
  • 18
  • [this](http://stackoverflow.com/questions/4124638/how-to-delete-a-drawn-circle-in-c-sharp-windows-form) or [this](http://stackoverflow.com/questions/37908570/how-to-delete-a-drawn-line-on-a-form) might be of help – Mong Zhu Feb 17 '17 at 09:59

1 Answers1

1

There seems a bit a problem with approach. You need to treat all the things as objects, but once You draw them, the information (of their location) is lost.

What to do?

Create class structure describing Your Actor, UseCase and Relations between them. It depends on Your concept where some time should be spent to create it. Each of this objects will have parameters like Location, Name and some more info (e.g. for drawing).

On program start You will create a collection, where You will hold all this objects. Once user select the object and click to delete it, You will remove it from the collection.

On any change in collection You will just refresh the location of drawing, which will redraw all objects from the collection.

Note: I will put this separated into files (first line) so You get a general idea how to structure it. Namespaces/usings omitted for brevity.

Actor.cs:

public class Actor
{
    public int X { get; set; }
    public int Y { get; set; }
    public string Name { get; set; }
    public List<UseCase> UseCases { get; set; } //keeping UseCases as reference - relation

    public Actor() { UseCases = new List<UseCase>(); }
}

UseCase.cs:

public class UseCase
{
    public int X { get; set; }
    public int Y { get; set; }
    public string Name { get; set; }
}

Form1.cs (code-file):

public class Form1 : Form
{
    public List<Actor> Actors = new List<Actor>();

    public void Add()
    {
        //creating new actor based on input + adding to collection
        var lAct = new Actor() { X = 10, Y = 20, Name = "Actor1" };
        Actors.Add(lAct);

        NotifyRedraw();
    }

    public void Remove(string aName)
    {
        var lAct = Actors.FirstOrDefault( a => a.Name == aName);
        if (lAct != null)
            Actors.Remove(lAct);

        NotifyRedraw();
    }

    public void NotifyRedraw()
    {
        this.panel1.Refresh();
    }

    /* call methods above from clicking the buttons*/
    public void Draw(Graphics g)
    {
        g.Clear(); //clear the graphics to make fresh drawing

        foreach (Actor a in Actors)
        {
            g.DrawCircle( /* implementation of drawing Actor */);
            foreach(UseCase u in a)
            {
                g.DrawRectangle( /* implementation of drawing UseCase */ );
                g.DrawLine(Pens.Red, a.X, a.Y, u.X, u.Y); //implementation of drawing Relation

            }
        }

    }
}

If You want to follow more deeply the OOP approach, You should actually not call g.DrawSth from the "General" method, but from each object (so each object know how to draw itself).

public class Actor
{
    // .... implementation of above properties
    private const int cSIZE = 10;

    public void Draw(Graphics g)
    {
        //implementation of drawing for object
        g.DrawCircle(Brushes.Blue, this.X, this.Y, cSIZE, cSIZE); 
    }
}

From Form1 class and Draw() method, You will call:

public void Draw(Graphics g)
{
    foreach(Actor a in Actors)
        a.Draw(g);
}
Tatranskymedved
  • 4,194
  • 3
  • 21
  • 47