如何从面板上绘制的椭圆列表中获取索引并删除椭圆?

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

我正在制作一个应用程序,我必须在面板上画东西。我列出了 "Ellipsis" 并将省略号绘制到面板上。

假设我在面板上绘制了 10 个省略号,我想删除第 5 个。我该怎么做?

我在每个椭圆后面制作了一个矩形,以便我可以点击它。

我知道有一种方法叫做:"list1.RemoveAt()"。这里的问题是我不知道列表的索引。单击椭圆时如何找到它的索引?

或者我不应该使用 list1.removeAt()?

这是代码:

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

变量 usecase 在本例中是一个椭圆。这是我的 panelUseCase_MouseClick 方法中的最后一个 if 语句。如您所见,我有 drawuc.RemoveAt()。但是我必须在()之间放置一个索引。但是我不知道索引,我想通过点击usecase来获取索引。有人有想法吗?

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

这将在 FindIndex 方法中使用您的 if 子句:

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

要删除您必须将其设置为 null 的元素。然后你可以将它从你身上移除 collection 并使你的面板无效。

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

    panelUseCase.Invalidate();
}

这是一个小程序,通过鼠标单击在面板上绘制椭圆ps,并在选中CheckBoxDelete 时将其删除。我试图使名称适合您的更新代码。这是一个精简到(我认为)您要求的基本要素的小示例。您可以将其复制粘贴、编译并 运行 到一个 WinForms 项目中,该项目具有一个名为 panelUseCase 的面板和一个名为 checkBoxDelete 的复选框。只需添加 2 个事件即可开始。

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

我想您可以采用该解决方案来解决您的问题。我希望这个帮助ps.

ps。这是我使用的 UseCase class 实现:

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