简体   繁体   中英

How to get index from a list of drawn ellipses on a panel and delete the ellipse?

I am making an app where I have to draw things on a panel. I made a list of "Ellipsis" and draw the Ellipsis to a panel.

Lets say I have 10 Ellipsis drawn on the panel and I want to delete the 5th. How do I do that?

For each ellipse I made a rectangle behind it so that I can click on it.

I know there is a method called: "list1.RemoveAt()". The problem here is that I don't know the index of the list. How do I find the index of an ellipse when clicking on it?

Or shouldn't I use list1.removeAt()?

this is the code:

private void panelUseCase_MouseClick(object sender, MouseEventArgs e)
{
    x = e.X;
    y = e.Y;
    else if (rbUseCases.Checked && radioTest.Checked)
    {
        foreach (UseCase usecase in usecases)
        {

            if (x >= usecase.Field.Left && x <= usecase.Field.Right && y >= usecase.Field.Top && y <= usecase.Field.Bottom)
            {
                int bla = usecases.IndexOf(usecase);
                drawuc.RemoveAt(bla);
                panelUseCase.Invalidate();
            }
        }
    }
}

The variable usecase is in this case an ellipse. It's the last if statement from my panelUseCase_MouseClick method. As you can see, I have drawuc.RemoveAt() . Yet I have to put an index between (). But I don't know the index and I want to get the index by clicking on a usecase . Someone got an Idea?

How do I find the index of an ellipse when clicking on it?

that would be using your if clause in the FindIndex method:

int index = usecases.FindIndex(el =>
            x >= el.Field.Left && 
            x <= el.Field.Right && 
            y >= el.Field.Top && 
            y <= el.Field.Bottom
            );

to delete the element you have to set it to null . Then you can remove it from you collection and invalidate your panel.

if (index >= 0)
{
    usecases[index] = null;
    usecases.RemoveAt(index);

    panelUseCase.Invalidate();
}

Here is a small program that draws ellipses on a panel by mouse click and deletes them when the CheckBoxDelete is checked. I tried to fit the names to the updated code of yours. This is a small example stripped down to the essentials that (I think) you asked for. You can copy paste, compile and run it into a WinForms project with a panel named panelUseCase and a checkbox named checkBoxDelete . Just add the 2 events and you are ready to go.

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

    List<UseCase> usecases = new List<UseCase>();
    int x, y;
    UseCase _usecase;

    private void panelUseCase_MouseClick(object sender, MouseEventArgs e)
    {
        x = e.X;
        y = e.Y;

        if (checkBoxDelete.Checked && usecases.Any())
        {
            int index = usecases.FindIndex(el =>
            x >= el.Field.Left && 
            x <= el.Field.Right && 
            y >= el.Field.Top && 
            y <= el.Field.Bottom
            );

            if (index >= 0)
            {
                usecases[index] = null;
                usecases.RemoveAt(index);

                panelUseCase.Invalidate();
            }
        }
        else
        {
            if (!String.IsNullOrWhiteSpace(textBoxUseCaseName.Text)) // if name is typed into textbox
            {
                _usecase = new UseCase()
                {
                    Name = textBoxUseCaseName.Text,
                    X = x,
                    Y = y,
                    Field = new Rectangle(x, y, 40, 40)
                };

                usecases.Add(_usecase);

                panelUseCase.Invalidate();
            }
            else
            {
                MessageBox.Show("Need a Name for Usecase!");
            }
        }
    }

    private void panelUseCase_Paint(object sender, PaintEventArgs e)
    {
        Graphics g = panelUseCase.CreateGraphics();
        Pen p = new Pen(Color.Red);

        foreach (var el in usecases)
        {
            g.DrawEllipse(p, el.Field);
        }
    }
}

I guess you can fit that solution to accommodate for your problem. I hope this helps.

ps. This is the UseCase class implementation that I used:

public class UseCase
{
    public string Name { get; set; }
    public Point MyPoint { get; set; }
    public Rectangle Field { get; set; }
    public int X { get; set; }
    public int Y { get; set; }

    public UseCase()
    {
        MyPoint = new Point();
        Field = new Rectangle();
    }      
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM