在 C# 中删除所有具有相同父级的动态创建的 PictureBoxes

Delete all dynamically created PictureBoxes with the same parent in c#

我正在用 C# 编写一个 windows 表单应用程序,我在其中动态创建 TextBoxes 和 PictureBoxes,并将 Panel 作为父级:

PictureBox pb = new PictureBox();
pb.Parent = MainPanel;
pb.Name = "pb" + "r" + NumberInRow + "c" + NumberInColumn+ "bi" + buildIndex;
pb.Location = new Point(30 * NumberInRow + 192 * (NumberInRow - 1), 50 * NumberInColumn + 273 * (NumberInColumn - 1));
pb.ImageLocation = ThumbLinks[i];

TextBox tb = new TextBox();
tb.Parent = MainPanel;
tb.Name = "tb" + "r" + NumberInRow + "c" + NumberInColumn + "bi" + buildIndex;
tb.Location = new Point(pb.Location.X - 4, pb.Location.Y + pb.Size.Height + 5);
tb.Text = GalleryNames[i];

我正在尝试用这个删除它们:

foreach (PictureBox pb in MainPanel.Controls)
    {
                MainPanel.Controls.Remove(pb);
    }

foreach (TextBox tb in MainPanel.Controls)
     {
                MainPanel.Controls.Remove(tb);
     }

虽然这似乎只有效一次。 Visual Studio 告诉我它无法将 System.Windows.Forms.TextBox 转换为 System.Windows.Forms.PictureBox

有没有办法以不同方式删除 PictureBoxes 和 TextBoxes?

我读过类似 MainPanel.Children.Remove(); 的内容,但它似乎不存在或者我做错了什么。

foreach (var control in MainPanel.Controls
                        .Where(c => c is PictureBox) || c is TextBox)
{
     MainPanel.Controls.Remove(control);
}

这将删除每个项目的类型,包括 PictureBoxTextBox。这段代码的问题当然是您在枚举集合的同时修改它。

解决此问题的一种方法是构建一个控件集合以先删除

var controls = MainPanel.Controls.Where(c => c is PictureBox || c is TextBox).ToList();

然后枚举该集合,从面板中删除每个项目。

foreach (var toRemove in controls)
     MainPanel.Controls.Remove(toRemove);

确保从 UI 的正确线程

中删除该项目将进一步有益
delegate void RemoveControlDelegate(Control controlToRemove);

private void RemoveControl(Control control)
{
   if (InvokeRequired)
   {
       BeginInvoke(new RemoveControlDelegate(RemoveControl), control);
   }
   else
   {
       MainPanel.Controls.Remove(control);
   }
}

foreach (var toRemove in controls)
     RemoveControl(toRemove);

查看 MainPanel.Controls.OfType<PictureBox>()MainPanel.Controls.OfType<TextBox>()。您可以将其与 .ToList() 调用结合使用,以避免在交互器仍处于活动状态时对其进行修改:

var PBs = MainPanel.Controls.OfType<PictureBox>().ToList();
var TBs = MainPanel.Controls.OfType<TextBox>().ToList();
foreach (var pb in PBs)
{
    MainPanel.Controls.Remove(pb);
}
foreach (TextBox tb in TBs)
{
    MainPanel.Controls.Remove(tb);
}