Найти node нажав контекстное меню

Как узнать, какой node в списке деревьев контекстное меню активировано? Например, щелкните правой кнопкой мыши по node и выберите в меню пункт.

Я не могу использовать свойство TreeViews SelectedNode, потому что node только щелкнул правой кнопкой мыши и не был выбран.

Ответ 1

Вы можете добавить событие мыши к TreeView, а затем выбрать правильный node с помощью GetNodeAt с учетом координат мыши, предоставленных MouseEventArgs.

void treeView1MouseUp(object sender, MouseEventArgs e)
{
    if(e.Button == MouseButtons.Right)
    {
        // Select the clicked node
        treeView1.SelectedNode = treeView1.GetNodeAt(e.X, e.Y);

        if(treeView1.SelectedNode != null)
        {
            myContextMenuStrip.Show(treeView1, e.Location);
        }
    }
}

Ответ 2

Вот мое решение. Поместите эту строку в событие NodeMouseClick TreeView:

 ((TreeView)sender).SelectedNode = e.Node;

Ответ 3

Я считаю, что поведение поведенческого поведения по умолчанию в дереве дерева выглядит довольно раздражающим. Например, если вы используете проводник и щелкните правой кнопкой мыши по node и нажмите "Свойства", он выделит node и отобразит диалог свойств для node, на который вы нажали. Но когда вы вернетесь из диалога, выделенный node был ранее выбранным/выделенным node, прежде чем щелкнуть правой кнопкой мыши. Я нахожу, что это вызывает проблемы удобства использования, потому что я навсегда запутался в том, действовал ли я правильно node.

Итак, во многих наших графических интерфейсах мы меняем выбранное дерево node на правую кнопку мыши, чтобы не было путаницы. Это может быть не то же самое, что и стандартное приложение iwndos, такое как Explorer (и я, как правило, сильно моделирую наше поведение графического интерфейса после стандартных приложений окна по причинам, описанным нами), я считаю, что этот один случай исключения приводит к гораздо более полезным деревьям.

Вот какой код, который меняет выбор во время правого щелчка:

  private void tree_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
  {
     // only need to change selected note during right-click - otherwise tree does
     // fine by itself
     if ( e.Button == MouseButtons.Right )
     {         
        Point pt = new Point( e.X, e.Y );
        tree.PointToClient( pt );

        TreeNode Node = tree.GetNodeAt( pt );
        if ( Node != null )
        {
           if ( Node.Bounds.Contains( pt ) )
           {
              tree.SelectedNode = Node;
              ResetContextMenu();
              contextMenuTree.Show( tree, pt );
           }
        }
     }
  }

Ответ 4

Возрождение этого вопроса, потому что я считаю, что это гораздо лучшее решение. Вместо этого я использую событие NodeMouseClick.

void treeview_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    if( e.Button == MouseButtons.Right )
    {
        tree.SelectedNode = e.Node;
    }
}

Ответ 5

Как и ответ Маркуса, это было решение, которое я нашел для меня:

private void treeView_MouseClick(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        treeView.SelectedNode = treeView.GetNodeAt(e.Location);
    }
}

Вам не нужно отображать контекстное меню самостоятельно, если вы установите его для каждого node следующим образом:

TreeNode node = new TreeNode();
node.ContextMenuStrip = contextMenu;

Затем внутри события ContextMenu Opening свойство TreeView.SelectedNode будет отображать правильный node.

Ответ 6

Это очень старый вопрос, но я все же нашел его полезным. Я использую комбинацию некоторых из приведенных выше ответов, потому что я не хочу, чтобы node с правой кнопкой мыши стал выбраннымNode. Если у меня есть корень node и вы хотите удалить один из его дочерних элементов, я не хочу, чтобы ребенок был выбран, когда я его удаляю (я также делаю некоторую работу над выбраннымNode, который я не хочу делать на щелчок правой кнопкой мыши). Вот мой вклад:

// Global Private Variable to hold right-clicked Node
private TreeNode _currentNode = new TreeNode();

// Set Global Variable to the Node that was right-clicked
private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Right)
        _currentNode = e.Node;
}

// Do something when the Menu Item is clicked using the _currentNode
private void toolStripMenuItem_Clicked(object sender, EventArgs e)
{
    if (_currentNode != null)
        MessageBox.Show(_currentNode.Text);
}

Ответ 7

Если вы хотите, чтобы контекстное меню зависело от выбранного элемента, вам лучше всего двигаться, я думаю, это использовать код Jonesinator для выбора щелкнутого элемента. Содержимое контекстного меню может зависеть от выбранного элемента.

Выбор элемента первым, а не просто его использование для контекстного меню дает несколько преимуществ. Во-первых, пользователь имеет визуальную индикацию, по которой он нажал, и, таким образом, с каким элементом связано это меню. Во-вторых, это намного проще поддерживать совместимость с другими методами вызова контекстного меню (например, быстрыми клавишами).

Ответ 8

Вот как я это делаю.

private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Right)
        e.Node.TreeView.SelectedNode = e.Node;
}

Ответ 9

Другой вариант, с которым вы можете запустить, - это иметь глобальную переменную с выбранным node. Вам просто нужно использовать TreeNodeMouseClickEventArgs.

public void treeNode_Click(object sender, TreeNodeMouseClickEventArgs e)
{
    _globalVariable = e.Node;
}

Теперь у вас есть доступ к этим node и его свойствам.