2016-12-21 4 views
0

皆さんとメリークリスマスによくお越しください。ToolStripMenuItemにAddHandlerをContextMenuStrip.Openingイベントが動作していない

私は最近VBプロジェクトを継承し、機能を追加する必要があります。だから、私は以下のコードを持っています:

Private Sub AddItems() 
     Dim itemMenu = DirectCast(ContextMenuStrip.Items.Find("name", False)(0), ToolStripMenuItem) 

     For Each dbObject In dbObjects 
      Dim item As New ToolStripMenuItem(dbObject.Name) 
      item.Tag = dbObject 
      AddHandler item.Click, AddressOf Item_Click 
      itemMenu.DropDownItems.Add(item) 
     Next 
    End Sub 

    Private Sub RemoveItems() 
     Dim itemMenu = DirectCast(ContextMenuStrip.Items.Find("name", False)(0), ToolStripMenuItem) 

     For Each item As ToolStripItem In itemMenu.DropDownItems 
      RemoveHandler item.Click, AddressOf Item_Click 
     Next 

     itemMenu.DropDownItems.Clear() 
    End Sub 

    Private Sub ContextMenuStrip_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip.Opening 
     AddItems() 
    End Sub 

    Private Sub ContextMenuStrip_Closing(sender As Object, e As ToolStripDropDownClosingEventArgs) Handles ContextMenuStrip.Closing 
     RemoveItems() 
    End Sub 

    Private Sub Item_Click(sender As Object, e As EventArgs) 
     ' Do the work    
    End Sub 

ロジックは、有効なデータベースオブジェクトを毎回コンテキストメニューのサブメニューを埋めることです。

問題は、このコードが機能しないことです。コンテキストメニューにアイテムを完全に追加しますが、AddHandler item.Click, AddressOf Item_Clickは何もしません。

私がAddItems()をと呼ぶと、それは完璧に機能します。

ご協力いただければ幸いです。 WozzeC後

2016年12月22日ソリューションは、私が今しながら、少しのためにこれで遊んでてきたと私はあなたの問題を再現するために管理している

Private Sub AddItems() 
     RemoveItems() 
     Dim itemMenu = DirectCast(ContextMenuStrip.Items.Find("name", False)(0), ToolStripMenuItem) 

     For Each dbObject In dbObjects 
      Dim item As New ToolStripMenuItem(dbObject.Name) 
      item.Tag = dbObject 
      AddHandler item.Click, AddressOf Item_Click 
      itemMenu.DropDownItems.Add(item) 
     Next 
    End Sub 

    Private Sub RemoveItems() 
     Dim itemMenu = DirectCast(ContextMenuStrip.Items.Find("name", False)(0), ToolStripMenuItem) 

     For Each item As ToolStripItem In itemMenu.DropDownItems 
      RemoveHandler item.Click, AddressOf Item_Click 
     Next 

     itemMenu.DropDownItems.Clear() 
    End Sub 

    Private Sub ContextMenuStrip_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip.Opening 
     AddItems() 
    End Sub 

    Private Sub Item_Click(sender As Object, e As EventArgs) 
     ' Do the work    
    End Sub 
+0

'ToolStripMenuItem'コンストラクタは、私が代わりにその使用をお勧めしたいので' Click'イベントハンドラを取るオーバーロードがあります。 – jmcilhinney

+0

@jmcilhinney応答をありがとう。これはどちらもうまくいかない。まだ検索していますが、運はありません。 – shadow

答えて

1

答えます。あなたの頭痛の理由は、RemoveItemsがClickイベントの前に発生することです。したがって、RemoveHandlerを実行すると、clickイベントは消えます。

代わりに、ContextMenuItemsにクリックハンドラを追加しないことをお勧めします。代わりに、親ノードにDropDownItemClickedのEventHandlerを追加します。 Item.Clickが動作した場合と同じ結果になりますが、Handlersを動的に処理するという頭痛はありません。

また、RemoveItemsのContextMenuのClosingイベントからClosedイベントへの切り替えも試みました。しかし、無駄に私は恐れている。

この問題を解決する別の方法は、RemoveItemsをAddItemの最初の行に移動することです。次に、終了イベントとRemoveItemsへの呼び出しを削除します。つまり、新しいContextMenuを作成したい場合は、前のContextMenuを適切に配置します。これにより、ContextMenu項目が2回以上追加される未来のバグも解決されます。あなたが本当に速く複数回右クリックすると、現在あなたのために起こります。

+0

あなたは正しいです。問題は 'Item_Click'の前に' ContextMenuStrip_Closing'がトリガーされたことでした。解決策は、 'AddItems'の始めに' RemoveItems'を呼び出すことです。ありがとう、メリークリスマス、私の友人。 – shadow

関連する問題