【问题标题】:Delete all dynamically created PictureBoxes with the same parent in c#在c#中删除所有具有相同父级的动态创建的PictureBox
【发布时间】:2019-02-28 07:02:47
【问题描述】:

我正在用 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

有没有办法以不同的方式删除图片框和文本框?

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

【问题讨论】:

  • 你得到的错误是因为面板内的元素类型是图片框和文本框,所以你不能使用 Foreach 并将它们全部转换为图片框/文本框。此外,如果从 Foreach 循环中的列表中删除项目,它将无法正常工作。如果您想删除所有这些,请使用while (MainPanel.Controls.Count > 0) MainPanel.Controls.RemoveAt(0);。我希望它有所帮助。
  • 是的,删除所有这些都适用于我的应用程序。谢谢:)

标签: c# dynamic textbox parent-child picturebox


【解决方案1】:
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);

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 是的,我认为 foreach 中的 PictureBox 只会寻找 PictureBoxes。这就是我一直在寻找的,
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-07
    相关资源
    最近更新 更多