我是否需要明确处理自定义的contextmenustrip

时间:2011-11-07 21:58:16

标签: vb.net contextmenustrip

我有一个类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中处置对象/资源?

1 个答案:

答案 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