我是否需要显式处置自定义的上下文菜单条

发布于 2024-12-14 07:42:20 字数 1325 浏览 5 评论 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 中处置对象/资源?

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

錯遇了你 2024-12-21 07:42:20

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

因为 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

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:

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

To call this new constructor from within your form or user control:

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

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:

Private components As System.ComponentModel.IContainer

In your constructor:

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

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):

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文