我是否需要显式处置自定义的上下文菜单条
我有一个类 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 中处置对象/资源?
I have a class clsContextPopUpMenu
to create a ContextMenuStrip with some basic functions (e.g.copy) that I can use in different controls.
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
For example, I can use it in a DataGridView DGVTable:
Private m_objPopUpMenu As clsContextPopUpMenu
m_objPopUpMenu = New clsContextPopUpMenu(CType(DGVTable, System.Windows.Forms.Control))
However, note that m_objPopUpMenu
IS NOT associated with the form having the above datagridview. According to ContextMenuStrip constructor explanation in MSDN, I think that m_objPopUpMenu
cannot be disposed automatically since it is not a child of the form.
My question is, do I have to explicitly dispose m_objPopUpMenu
in designer:
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
A broader question is that when should I dispose objects/resource by myself? Of course, gc collector is not a magician to release all available memory. Can I always dispose objects/resource in Dispose Sub as shown above?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于更好地理解问题而修改了答案:
因为 ContextMenuStrip 实现了 IDisposable,所以您需要将其添加到表单管理的组件列表中,以便正确且自动地处理它,或者管理处理正如您最初问题中所建议的那样。
这是您的类的修订版,它将支持自动处理,就像您将 ContextMenuStrip 直接添加到表单时 Windows 处理它一样:
要从表单或用户控件中调用这个新的构造函数:
请注意,我还从构造函数中删除了
ByRef
,因为它不是必需的,这也消除了在将控件传递给构造函数之前对其进行强制转换的需要。附加说明:过去(“过去”)组件不一定出现在每个表单或用户控件上。我相信这已经改变/已修复,但如果您发现自己没有,很容易手动添加:
在您的构造函数中:
在您的 Dispose 方法中(我已经添加了完整的 dispose 方法,以防它尚不存在;如果它是,只是添加了组件相关的代码):
Revised answer due to better understanding of issue:
Because the ContextMenuStrip implements IDisposable, you will either need to add it to the list of Components managed by the form so that it is disposed appropriately and automatically or manage the disposal yourself as suggested in your original question.
Here is a revision of your class that will support the automatic disposal in the same way that windows would handle it if you were to add ContextMenuStrip directly to the form:
To call this new constructor from within your form or user control:
Note that I also removed the
ByRef
from the constructor since it is not required, which also eliminates the need to cast the controls before passing them to the constructor.One additional note: it used to be ("back in the day") that components was not necessarily present on every form or user control. I believe that this has changed/been fixed, but if you find yourself without, it is easy to add manually:
In your constructor:
In your Dispose method (I have added the full dispose method in case it is not already present; if it is, just added the components-related code):