2011-11-07 15 views
0

私はクラスclsContextPopUpMenuを持っていて、異なるコントロールで使用できるいくつかの基本的な機能(例えば、コピー)を持つContextMenuStripを作成しています。例えば私は明示的にカスタマイズした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 

、Iは、しかしのDataGridViewにDGVTable:

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

を使用することができm_objPopUpMenuは、上記のDataGridViewを有するフォームに関連付けられていないことに注意してください。 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でオブジェクト/リソースをいつでも処分できますか?

答えて

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 

からこの新しいコンストラクタを呼び出すにはまた、コンストラクタに渡す前にコントロールをキャストする必要がなくなり、それが必要とされていないので、私はまた、コンストラクタからByRefを削除

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

注:フォームまたはユーザーコントロール内。

もう1つ注意してください:コンポーネントは必ずしもすべてのフォームまたはユーザーコントロールに存在するとは限りませんでした。私は、これは修正されて/変更されたことを信じているが、手動で追加するのは簡単である、なしに、あなたは自分自身を見つける場合:

Private components As System.ComponentModel.IContainer 

あなたのコンストラクタでは:あなたのDisposeメソッドで

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

(私が追加しましたそれが既に存在しない場合は完全な処理メソッド、それが存在する場合はコンポーネント関連のコードを追加しました):

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 
+0

ありがとうございました。私はなぜこの実装が複数のフォームで乱雑になるのか理解していません。クラスclsContextPopUpMenuは独立したクラスです。各フォームは、clsContextPopUpMenuのNewを呼び出すことによって、clsContextPopUpMenuの独自のオブジェクトを開始します。しかし、どのように各フォームのオブジェクトをリリースするには? (あなたが言及したように、フォームレベルの変数を何も設定しないでください。m_objPopUpMenu = nothingを設定するのはどうですか?これはオブジェクトを処理するコードと違うのですか?) – Summer

+0

各フォームがclsContextPopUpMenuをインスタンス化するときに、その参照をフォーム内の変数に格納しますか?これを行うと、コードを追加する必要はありません。標準の.Net GC収集プロセスがすべてを処理します。フォームの外部に参照を格納する場合(たとえばModule内など)、フォームのコードを追加してアイテムの破棄を管理する必要があります。 –

+0

私は、clsContextPopUpMenuをインスタンス化するときに、フォーム内の変数に参照を格納します。 GCはアンマネージドリソースを処理できないことに注意してください。グラフィックスオブジェクトなので、コンテキストメニューストリップは管理されていないリソースだと思っていました。私の理解は間違っていますか?御時間ありがとうございます! – Summer

関連する問題