删除控件

时间:2012-03-11 08:04:55

标签: .net vb.net controls

我在表单(144)上有很多需要删除的按钮。他们所有的名字都以“R”开头。所以我使用了这段代码。

Sub RemoveBookingButtons()
    Dim cntrl As Control

    For Each cntrl In Me.Controls
        If Mid(cntrl.name, 1, 1) = "R" Then
            Me.Controls.Remove(cntrl)
        End If
    Next

End Sub

但是,无论何时运行此子功能,它都会删除以“R”开头的所有其他按钮。有人可以建议更好的代码,或指出该代码中是否有缺陷,或者它隐藏在我程序中的其他地方。

3 个答案:

答案 0 :(得分:2)

迭代期间不要更改Collection

您可以使用OfType查找所有Buttons

Dim rButtons = Me.Controls.OfType(Of Button)().
    Where(Function(btn) btn.Name.StartsWith("R")).ToList()
For Each btn In rButtons
    Me.Controls.Remove(btn)
Next

澄清此代码:

一般情况下,这是LINQ-to-Objects

Me.Controls.OfType(Of Button)()

这将返回表单ControlCollection of Type Button中的所有控件。

.Where(Function(btn) btn.Name.StartsWith("R"))

这会将结果集限制为Name StartsWith“R”的按钮(请注意,这是区分大小写的,如果希望它不区分大小写,则需要先调用ToLower/ToUpper )。

.ToList()

这会从List(Of Button)创建IEnumerable(OfButton)。并不是任何LINQ查询都将被延迟执行。 Deferred execution表示表达式的评估被延迟,直到实际需要实现的值。因此,在任何消耗它之前,查询不会实现,在这种情况下,ToList()执行它并创建列表。

答案 1 :(得分:0)

你正在修改你正在迭代的集合,所以它肯定会出错。我很惊讶它甚至跑了。

您应该将所有匹配的控件检索到一个新列表中,然后遍历该列表,从第一个列表中删除。

在C#中:

var toRemove = this.Controls.Where( ctrl => ctrl.Name.StartsWith("R") ).ToList();
foreach( var ctrl in toRemove )
{
    this.Controls.Remove(ctrl);
}

在VB中:

dim toRemove = (from c in Me.Controls where c.StartsWith("R") select c).ToList()

for each ctrl in toRemove
  Me.Controls.Remove(ctrl)
next

答案 2 :(得分:0)

解决问题的最小方法是使用For循环而不是For Each,
从控件集合的结尾开始,如

For i = Me.Controls.Count -1 To 0
  Dim cntrl as Control = Me.Controls(i)
  If Mid(cntrl.name, 1, 1) = "R" Then 
      Me.Controls.Remove(cntrl) 
  End If 
Next