Вопрос

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

Я не могу использовать 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);
        }
    }
}

Другие советы

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top