2008-08-05 25 views
61

Làm cách nào để tìm ra nút nào trong danh sách cây trình đơn ngữ cảnh đã được kích hoạt? Ví dụ, nhấp chuột phải vào một nút và chọn một tùy chọn từ trình đơn.Tìm nút được nhấp trong menu ngữ cảnh

Tôi không thể sử dụng thuộc tính TreeViews 'SelectedNode vì nút này chỉ được nhấp chuột phải và không được chọn.

Trả lời

83

Bạn có thể thêm sự kiện nhấp chuột vào TreeView, sau đó chọn nút chính xác bằng cách sử dụng GetNodeAt cho các tọa độ chuột được cung cấp bởi 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); 
     } 
    } 
} 
+4

Cảm ơn bạn rất nhiều, tôi có một bổ sung nhỏ cho giải pháp: Bạn cũng có thể sử dụng sự kiện "_NodeMouseClick" cung cấp cho bạn một "TreeNodeMouseClickEventArgs e" trong trường hợp này bạn chỉ có thể sử dụng e.Node và không có bận tâm với việc kiểm tra thời gian nút là null hay không. – SDM

+0

Tôi nhận được kết quả mong muốn với sự kiện MouseDown thay vì MouseUp. – Javier

0

Nếu bạn muốn menu ngữ cảnh phụ thuộc vào mục đã chọn, bạn nên di chuyển tốt nhất Tôi nghĩ là sử dụng mã của Jonesinator để chọn mục được nhấp. Nội dung menu ngữ cảnh của bạn sau đó có thể phụ thuộc vào mục đã chọn.

Chọn mục đầu tiên thay vì chỉ sử dụng cho menu ngữ cảnh sẽ mang lại một số lợi thế. Đầu tiên là người dùng có một dấu hiệu trực quan về cái mà anh ta đã nhấp vào và do đó mục menu được liên kết với. Thứ hai là theo cách này, việc tiếp tục tương thích với các phương thức gọi trình đơn ngữ cảnh khác dễ dàng hơn nhiều (ví dụ: phím tắt).

11

Tôi thấy các hành vi chọn lựa hành vi chọn lựa cửa sổ tiêu chuẩn là khá khó chịu. Ví dụ: nếu bạn đang sử dụng Explorer và nhấp chuột phải vào nút và nhấn Thuộc tính, nó sẽ làm nổi bật nút và hiển thị hộp thoại thuộc tính cho nút bạn đã nhấp vào. Nhưng khi bạn quay trở lại từ hộp thoại, nút được đánh dấu là nút được chọn trước đó/được đánh dấu trước khi bạn nhấp chuột phải. Tôi thấy điều này gây ra vấn đề về khả năng sử dụng bởi vì tôi mãi mãi bị nhầm lẫn về việc liệu tôi có hoạt động trên nút bên phải hay không.

Vì vậy, trong nhiều GUI của chúng tôi, chúng tôi thay đổi nút cây đã chọn khi nhấp chuột phải để không có nhầm lẫn. Điều này có thể không giống như một ứng dụng iwndos chuẩn như Explorer (và tôi có xu hướng mô hình hóa mạnh mẽ hành vi GUI của chúng tôi sau các ứng dụng cửa sổ chuẩn vì lý do usabiltiy), tôi tin rằng trường hợp ngoại lệ này dẫn đến các cây có thể sử dụng được nhiều hơn.

Dưới đây là một số mã rằng những thay đổi lựa chọn trong thời gian click chuột phải:

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

Đây là giải pháp tốt nhất cho tôi bởi vì nó thực sự chọn nút bạn nhấp vào. –

18

Đây là giải pháp của tôi. Đặt dòng này vào NodeMouseClick sự kiện của TreeView:

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

Sự kiện chuột args không có .Node –

+2

Vâng nhưng TreeNodeMouseClickEventArgs (được chuyển vào sự kiện ** NodeMouseClick **). Vì vậy, giải pháp của tôi là làm việc và không quá phức tạp như một số giải pháp khác – deej

+1

Đẹp và đơn giản – AndrewJE

2

Tương tự như Marcus' câu trả lời, đây là giải pháp tôi tìm thấy làm việc cho tôi:

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

Bạn không cần phải hiển thị menu ngữ cảnh chính mình nếu bạn đặt nó vào từng nút riêng lẻ như vậy:

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

Sau đó, bên trong sự kiện khai trương của ContextMenu, tài sản TreeView.SelectedNode sẽ phản ánh đúng nút.

6

Khôi phục câu hỏi này vì tôi thấy đây là giải pháp tốt hơn nhiều. Thay vào đó, tôi sử dụng sự kiện NodeMouseClick.

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

giống như của tôi =) – deej

+0

Tôi thích điều này tốt hơn nhiều. –

0

Đây là cách tôi thực hiện.

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

Đây là câu hỏi rất cũ, nhưng tôi vẫn thấy nó hữu ích.Tôi đang sử dụng kết hợp một số câu trả lời ở trên, vì tôi không muốn nút được nhấp chuột phải để trở thành nút đã chọn. Nếu tôi đã chọn nút gốc và muốn xóa một trong số đó là con, tôi không muốn con được chọn khi tôi xóa nó (tôi cũng đang thực hiện một số công việc trên nút đã chọn mà tôi không muốn xảy ra ở bên phải nhấp chuột). Đây là đóng góp của tôi:

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

Một tùy chọn khác bạn có thể chạy với là có biến toàn cầu có nút đã chọn. Bạn chỉ cần sử dụng TreeNodeMouseClickEventArgs.

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

Bây giờ bạn có quyền truy cập vào nút đó và thuộc tính của nút đó.