Найти узел, на котором щелкнули в контекстном меню

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

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

Решение

Вы можете добавить событие щелчка мыши в TreeView, а затем выбрать нужный узел с помощью 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)sender).SelectedNode = e.Node;
Комментарии (4)

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

Поэтому во многих наших графических интерфейсах мы меняем выбранный узел дерева при щелчке правой кнопкой мыши, чтобы не было путаницы. Это может быть не так, как в стандартном приложении 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 );
           }
        }
     }
  }
Комментарии (1)

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

void treeview_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    if( e.Button == MouseButtons.Right )
    {
        tree.SelectedNode = e.Node;
    }
}
Комментарии (2)

Это очень старый вопрос, но я все-таки нашел его полезным. Я использую сочетание некоторых из перечисленных выше ответов, потому что я Дон'т хотим, Правой Кнопкой Мыши узел, чтобы стать selectedNode. Если у меня есть корневой узел выбран и хотите удалить его'ы дети, я не'т хотите, чтобы ребенок выбран, когда я удалить его (я также делаю некоторые работы по selectedNode, что я Дон'т хотите, чтобы произошло на правой кнопки мыши). Вот мой вклад:

// 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);
}
Комментарии (0)

Похожие в Marcus' Ответ, Это было решение, которое я нашел работает для меня:

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

Вам не нужно показать контекстное меню сами, если вы установите его к каждому отдельному узлу:

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

Затем в контекстное меню'с открытием событие TreeView элемент.Свойство SelectedNode будет отражать правильный узел.

Комментарии (0)

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

private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Right)
        e.Node.TreeView.SelectedNode = e.Node;
}
Комментарии (0)

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

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

Комментарии (0)

Другой вариант можно запускать С является глобальной переменной, которая имеет выбранный узел. Вы просто должны использовать TreeNodeMouseClickEventArgs.

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

Теперь у вас есть доступ к этому узлу, и он's свойства.

Комментарии (0)