我正在用C#编写Windows窗体应用程序,在其中我以Panel为父级动态创建TextBoxes和PictureBoxes:
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
。
有什么方法可以不同地删除PictureBox和TextBox吗?
我已经读过类似MainPanel.Children.Remove();
之类的东西,但是它似乎不存在或者我做错了事。
答案 0 :(得分:0)
foreach (var control in MainPanel.Controls
.Where(c => c is PictureBox) || c is TextBox)
{
MainPanel.Controls.Remove(control);
}
这将删除类型为PictureBox
和TextBox
的每个项目。当然,此代码的问题是您在枚举集合的同时对其进行了修改。
解决此问题的一种方法可能是构建一组控件以首先删除
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);
答案 1 :(得分:-1)
查看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);
}