【问题标题】:Dynamically Removing controls from a form从表单中动态删除控件
【发布时间】:2021-07-25 13:21:50
【问题描述】:

我使用的表单具有根据所使用对象的类动态添加的控件。 为了将下一个对象加载到表单中,有必要删除并重建动态部分。 我在使用下面的代码删除对象时遇到随机结果,您能告诉我我的错误可能在哪里吗?

Sub CntrlKill(KillName As String)
    For Each c In Me.Controls
        If Strings.InStr(c.name, KillName) > 0 Then
            Me.Controls.Remove(c)
        End If
    Next
End Sub

【问题讨论】:

  • KillName 来自哪里?它是否代表控件的Name 属性的部分匹配(因此您应该检查c.Name.Contains(KllName))?所有控件都是Me 的子级(假设Me 是表单的实例)?-顺便说一句,删除控件,调用c.Dispose(),而不是Controls.Remove(c)(除非这些控件是可重用的对象集合的一部分)。- 发布添加这些控件的代码。
  • 这能回答你的问题吗? Removing controls in a loop
  • 这能回答你的问题吗? foreach control c# skipping controls
  • 永远不要使用 For Each 循环来枚举集合,然后在循环内修改该集合。那总是错的。

标签: vb.net


【解决方案1】:

将GSerg提供的第二个链接翻译成vb.net。

创建一个列表来保存您要删除的控件。您可以遍历所有控件并将某些控件添加到列表中。这不会影响 Controls 集合。我已经很久没有看到InStr 使用了。 .net .Contains 可能会满足您的需求。

第二个循环循环通过lstToDelete。从 Controls 集合中删除控件不会影响此列表。

For Each 循环的规则是不影响您正在循环的集合。您可以更改集合中项目的属性。只是不要删除任何项目。

Sub CntrlKill(KillName As String)
    Dim lstToDelete As New List(Of Control)
    For Each c As Control In Controls
        If c.Name.Contains(KillName) Then
            lstToDelete.Add(c)
        End If
    Next
    For Each c In lstToDelete
        c.Dispose()
    Next
End Sub

或者反向循环方式。

Private Sub NukeControls(KillString As String)
    For i = Controls.Count - 1 To 0 Step -1
        If Controls(i).Name.Contains(KillString) Then
            Controls(i).Dispose()
        End If
    Next
End Sub

【讨论】:

  • 控件的并行集合,不是必需的。您需要一个向后的 for 并在与 creteria 匹配的控件列表上调用 Dispose()。不要打电话给Remove()。一个控件,在处理后,也将从控件集合中删除。调用 Remove(),您只需从集合中删除 Control,但不会释放 Control。例如,dim controlsToRemove = Controls.OfType(Of Control).Where(Function(c) c.Name.Contains(KillName)).ToArray() for i as Integer = controlsToRemove.Length - 1 To 0 Step -1 controlsToRemove(i).Dispose() next
  • 无法使用foreach 循环,因为您修改了正在迭代的集合。因此,无论您调用Remove() 还是Dispose(),您都删除或处置了一半的控件。
  • @Jimi 我不是在迭代 Controls 集合,而是在迭代我的 List(OfT)
  • 这就是控件的并行集合不是必需的。部分的内容。如果您出于某种原因想使用另一个集合,您仍然需要调用Dispose(),而不是Remove(),原因已描述。当您拥有包含图形对象的控件时,差异变得非常明显。当您调用Remove() 时,这些对象都不会被释放。如果您继续添加/删除控件而不处置任何控件,您的应用可能(将)崩溃。关闭表单无济于事。
  • 对不起,玛丽 - 新来的 - 是的,它很有帮助,我刚刚接受了 - 非常感谢。
猜你喜欢
  • 1970-01-01
  • 2017-02-02
  • 2012-12-03
  • 2020-03-22
  • 2013-05-21
  • 1970-01-01
  • 2016-02-26
  • 2011-08-23
相关资源
最近更新 更多