0

我有一个类clsContextPopUpMenu来创建一个带有一些基本功能(例如复制)的 ContextMenuStrip,我可以在不同的控件中使用这些功能。

    Friend Sub New(ByRef objControl As System.Windows.Forms.Control)

    m_objControlContainer = objControl
    m_mnuCopyCell2Clipboard = New ToolStripMenuItem("Copy Cell")
    m_PopupMenu = New ContextMenuStrip
    m_PopupMenu.Items.AddRange(New ToolStripMenuItem() {m_mnuCopyCell2Clipboard})
End Sub

例如,我可以在 DataGridView 中使用它DGVTable:

 Private m_objPopUpMenu As clsContextPopUpMenu
 m_objPopUpMenu = New clsContextPopUpMenu(CType(DGVTable, System.Windows.Forms.Control))

但是,请注意,它m_objPopUpMenu与具有上述 datagridview 的表单无关。根据MSDN中的 ContextMenuStrip 构造函数解释,我认为m_objPopUpMenu不能自动处理,因为它不是表单的子项。

我的问题是,我是否必须m_objPopUpMenu在设计师中明确处置:

    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
    Try
        If disposing AndAlso components IsNot Nothing Then
            components.Dispose()
            **m_objPopUpMenu.Dispose()**
        End If
    Finally
        MyBase.Dispose(disposing)
    End Try
End Sub

一个更广泛的问题是,我应该什么时候自己处理对象/资源?当然,gc 收集器并不是释放所有可用内存的魔术师。如上所示,我是否可以始终在 Dispose Sub 中处理对象/资源?

4

1 回答 1

1

由于更好地理解问题而修改了答案:

因为 ContextMenuStrip 实现 IDisposable,您需要将其添加到表单管理的组件列表中,以便适当地自动处理它,或者按照原始问题中的建议自行管理处理。

这是您的类的修订版,它将支持自动处置,就像您将 ContextMenuStrip 直接添加到表单中时 Windows 会处理它一样:

Friend Sub New(ByVal objControl As System.Windows.Forms.Control, ByVal components As System.ComponentModel.IContainer)

    m_objControlContainer = objControl
    m_mnuCopyCell2Clipboard = New ToolStripMenuItem("Copy Cell")
    m_PopupMenu = New ContextMenuStrip(components)
    m_PopupMenu.Items.AddRange(New ToolStripMenuItem() {m_mnuCopyCell2Clipboard})
End Sub

要从您的表单或用户控件中调用这个新的构造函数:

 Private m_objPopUpMenu As clsContextPopUpMenu
 m_objPopUpMenu = New clsContextPopUpMenu(DGVTable, Me.components)

请注意,我还ByRef从构造函数中删除了它,因为它不是必需的,这也消除了在将控件传递给构造函数之前对其进行强制转换的需要。

另一个注意事项:过去(“过去”)组件不一定存在于每个表单或用户控件上。我相信这已更改/已修复,但如果您发现自己没有,手动添加很容易:

Private components As System.ComponentModel.IContainer

在您的构造函数中:

Me.components = New System.ComponentModel.Container()

在您的 Dispose 方法中(我添加了完整的 dispose 方法以防它不存在;如果存在,只需添加与组件​​相关的代码):

Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
    If disposing Then
        If Not (components Is Nothing) Then
            components.Dispose()
        End If
    End If
    MyBase.Dispose(disposing)
End Sub
于 2011-11-07T22:33:20.083 回答