IT Share you

컨텍스트 메뉴에서 클릭 한 노드 찾기

shareyou 2020. 11. 7. 17:56
반응형

컨텍스트 메뉴에서 클릭 한 노드 찾기


트리 목록에서 컨텍스트 메뉴가 활성화 된 노드를 어떻게 알 수 있습니까? 예를 들어 노드를 마우스 오른쪽 버튼으로 클릭하고 메뉴에서 옵션을 선택합니다.

SelectedNode노드가 마우스 오른쪽 버튼으로 클릭되고 선택되지 않았기 때문에 TreeViews의 속성을 사용할 수 없습니다 .


TreeView에 마우스 클릭 이벤트를 추가 한 다음 MouseEventArgs에서 제공하는 마우스 좌표가 주어지면 GetNodeAt을 사용하여 올바른 노드를 선택할 수 있습니다.

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

여기 내 해결책이 있습니다. 이 줄을 TreeView의 NodeMouseClick 이벤트에 넣습니다.

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

표준 Windows 트리보기 동작 선택 동작이 상당히 성가신다는 것을 알았습니다. 예를 들어, Explorer를 사용하고 노드를 마우스 오른쪽 버튼으로 클릭하고 Properties를 누르면 노드가 강조 표시되고 클릭 한 노드의 속성 대화 상자가 표시됩니다. 그러나 대화 상자에서 돌아 오면 강조 표시된 노드는 마우스 오른쪽 버튼을 클릭하기 전에 이전에 선택 / 강조 표시된 노드였습니다. 내가 올바른 노드에서 행동했는지에 대해 영원히 혼란 스럽기 때문에 이것이 사용성 문제를 일으킨다는 것을 알게되었습니다.

따라서 많은 GUI에서 우클릭으로 선택된 트리 노드를 변경하여 혼동이 없도록합니다. 이것은 Explorer와 같은 표준 iwndos 앱과 같지 않을 수 있습니다 (사용 성상의 이유로 표준 창 앱 이후에 GUI 동작을 강력하게 모델링하는 경향이 있습니다).이 예외 사례가 훨씬 더 유용한 트리를 생성한다고 생각합니다.

다음은 마우스 오른쪽 버튼을 클릭하는 동안 선택을 변경하는 몇 가지 코드입니다.

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

이것은 매우 오래된 질문이지만 여전히 유용하다는 것을 알았습니다. 마우스 오른쪽 버튼으로 클릭 한 노드가 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);
}

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;

Then inside the ContextMenu's Opening event, the TreeView.SelectedNode property will reflect the correct node.


If you want the context menu to be dependent on the selected item you're best move I think is to use Jonesinator's code to select the clicked item. Your context menu content can then be dependent on the selected item.

Selecting the item first as opposed to just using it for the context menu gives a few advantages. The first is that the user has a visual indication as to which he clicked and thus which item the menu is associated with. The second is that this way it's a hell of a lot easier to keep compatible with other methods of invoking the context menu (e.g. keyboard shortcuts).


Here is how I do it.

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

Another option you could run with is to have a global variable that has the selected node. You would just need to use the TreeNodeMouseClickEventArgs.

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

Now you have access to that node and it's properties.

참고URL : https://stackoverflow.com/questions/2527/find-node-clicked-under-context-menu

반응형