Найти узел нажал в контекстном меню - PullRequest
65 голосов
/ 05 августа 2008

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

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

Ответы [ 9 ]

87 голосов
/ 05 августа 2008

Вы можете добавить событие щелчка мыши в 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);
        }
    }
}
20 голосов
/ 09 декабря 2010

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

 ((TreeView)sender).SelectedNode = e.Node;
12 голосов
/ 12 декабря 2008

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

Таким образом, во многих наших графических интерфейсах мы изменяем выбранный узел дерева правой кнопкой мыши, чтобы не было путаницы. Это может не совпадать со стандартным приложением 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 );
           }
        }
     }
  }
6 голосов
/ 02 января 2013

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

void treeview_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    if( e.Button == MouseButtons.Right )
    {
        tree.SelectedNode = e.Node;
    }
}
2 голосов
/ 06 декабря 2016

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

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

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;

Тогда внутри события открытия ContextMenu свойство TreeView.SelectedNode будет отражать правильный узел.

0 голосов
/ 12 декабря 2016

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

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

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

0 голосов
/ 30 мая 2014

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

private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Right)
        e.Node.TreeView.SelectedNode = e.Node;
}
0 голосов
/ 08 августа 2008

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

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

...