Элемент ContextMenuStrip для выполнения различных действий в зависимости от того, кто его вызывает - PullRequest
1 голос
/ 19 апреля 2020

Я создал ContextMenuStrip с тремя различными элементами. Затем у меня есть TreeView с родительским и дочерним узлами. Я назначил ContextMenuStrip для обоих узлов следующим образом:

fatherNode.ContextMenuStrip = menuNodes
childNode.ContextMenuStrip = menuNodes

Проблема в том, что элементы из меню должны выполнять различные действия в зависимости от того, какой узел вызывает пункт меню. Другими словами, например, если первый элемент в меню «создать», он создаст что-то очень конкретное c, если его вызывает родительский узел, и другое, если дочерний элемент вызывает тот же элемент меню.

Надеюсь, я смог объяснить, что я имею в виду, и извините, у меня нет кода, потому что я понятия не имею, как мне этого добиться.

1 Ответ

1 голос
/ 21 апреля 2020

Предположим, у вас есть два метода:

Private Sub ParentNodeMethod()
    Console.WriteLine("Parent Node Method")
End Sub

Private Sub ChildNodeMethod()
    Console.WriteLine("Child Node Method")
End Sub

... и у вас есть ContextMenuStrip для элемента управления TreeView, и вы хотите, чтобы определенный c пункт меню (ToolStripMenuItem) вызывал - по щелчку - один из них в зависимости от того, какой TreeNode был выбран.

Вы можете использовать делегат Action и создавать различные действия, которые вызывают разные методы, и назначать их свойствам Tag рассматриваемых объектов TreeNode. обработайте TreeView.NodeMouseClick , чтобы показать ContextMenuStrip и передать правильное действие, и обработайте событие ItemClicked ContextMenuStrip, чтобы вызвать его.

Замените ваш код на :

'//
parentNode.Tag = New Action(AddressOf ParentNodeMethod)
childNode.Tag = New Action(AddressOf ChildNodeMethod)
'//

Private Sub TreeView1_NodeMouseClick(sender As Object,
                                     e As TreeNodeMouseClickEventArgs) _
                                     Handles TreeView1.NodeMouseClick

    If e.Button = MouseButtons.Right AndAlso TypeOf e.Node.Tag Is Action Then
        ContextMenuStrip1.Items(0).Tag = e.Node.Tag
        ContextMenuStrip1.Show(TreeView1, e.Location)
    End If
End Sub

Private Sub ContextMenuStrip1_ItemClicked(sender As Object,
                                          e As ToolStripItemClickedEventArgs) _
                                          Handles ContextMenuStrip1.ItemClicked
    If TypeOf e.ClickedItem.Tag Is Action Then
        DirectCast(e.ClickedItem.Tag, Action)()
        e.ClickedItem.Tag = Nothing
    End If
End Sub

Другой способ - создать Dictionary(Of TreeNode, Action) вместо назначения действий свойствам Tag:

'Class member
Private ReadOnly dict As New Dictionary(Of TreeNode, Action)
'//

dict.Add(parentNode, New Action(AddressOf ParentNodeMethod))
dict.Add(childNode, New Action(AddressOf ChildNodeMethod))
'//

Private Sub TreeView1_NodeMouseClick(sender As Object,
                                     e As TreeNodeMouseClickEventArgs) _
                                     Handles TreeView1.NodeMouseClick

    Dim a As Action = Nothing

    If e.Button = MouseButtons.Right AndAlso dict.TryGetValue(e.Node, a) Then
        ContextMenuStrip1.Items(0).Tag = a
        ContextMenuStrip1.Show(TreeView1, e.Location)
    End If
End Sub

Private Sub ContextMenuStrip1_ItemClicked(sender As Object,
                                          e As ToolStripItemClickedEventArgs) _
                                          Handles ContextMenuStrip1.ItemClicked
    If TypeOf e.ClickedItem.Tag Is Action Then
        DirectCast(e.ClickedItem.Tag, Action)()
        e.ClickedItem.Tag = Nothing
    End If
End Sub

В качестве альтернативы и, как уже упоминалось @Jimi, если объекты TreeNode того же Level должны вызывать один и тот же метод, а затем использовать это свойство, чтобы решить, какой метод следует вызывать. * 10 25 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...