我有一个类clsContextPopUpMenu
来创建一个ContextMenuStrip,它带有一些我可以在不同控件中使用的基本函数(例如.copy)。
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的表单无关。根据{{3}}中的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 collector不是释放所有可用内存的魔术师。如上所示,我是否可以在Dispose Sub中处置对象/资源?
答案 0 :(得分: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