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


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

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

9 62

9 ответов:

вы можете добавить событие щелчка мыши в 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);
        }
    }
}

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

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

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

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

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

  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 );
           }
        }
     }
  }

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

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

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

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 будет отражать правильный узел.

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

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

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

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

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

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

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

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