el nodo de vista de árbol está resaltado aunque no lo hice con el botón derecho del mouse en el nodo

Estoy trabajando en un formulario de ganancias y en mi interfaz de usuario hay una vista de árbol, encontré que el treenode se resaltará aunque no haya hecho clic en el nodo con el botón derecho del mouse (por ejemplo, Node1 se resaltará cuando haga clic en la siguiente posición). pero realmente no me gusta este comportamiento porque quiero mostrar un menú contextual diferente cuando no hice clic en un treenode

+ RootNode

|_ Node1 [ Right Click Here, Node1 will be highlighted] | |_ Node2 [ Right Click Here, Node2 will be highlighted] 

Al dejar de responder a la respuesta de Kevin Wienhold, solo desea permitir que el usuario haga clic en el espacio vacío de la vista de árbol y anule la selección de cualquier nodo seleccionado.

Puede hacer esto manejando el evento MouseDown del control TreeView y configurando la propiedad SelectedNode en null si se hizo clic con el mouse sobre una ubicación que no contiene un nodo. Por ejemplo, podrías usar el siguiente código:

 private void myTreeView_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) { if (myTreeView.HitTest(e.Location).Node == null) { myTreeView.SelectedNode = null; } } 

Esto aprovecha el método HitTest para determinar qué nodo se encuentra en un punto en particular, especificando la ubicación del evento del mouse como el punto a probar. No necesita ningún otro código para seleccionar los nodos como de costumbre cuando el usuario hace clic en ellos; que se maneja automáticamente por el TreeView .


EDITAR: Como indica mi comentario a la pregunta, todavía estoy excepcionalmente poco claro en cuanto a lo que está tratando de lograr aquí. Si realmente está interesado en evitar que un nodo se resalte temporalmente mientras mantiene presionado el botón derecho del mouse en el espacio vacío al lado del nodo, las cosas se vuelven un poco más complejas.

He analizado este problema anteriormente y lo difícil es que los mensajes de la ventana no se reciben mientras se mantiene presionado el botón del mouse, al menos no hasta que se mueva el mouse (en cuyo caso, el nodo ya no está seleccionado) . Este comportamiento es aparentemente dictado por el sistema operativo y no se anula fácilmente usando los eventos estándar proporcionados por .NET. Puede intentar cancelar un clic del botón derecho en el evento MouseDown todo el día, pero Windows está seleccionando el nodo antes de que este evento se active bajo su control (recuerde que los controles provistos por .NET como TreeView y ListView son simplemente envuelve alrededor de los mismos controles proporcionados por la API de Windows, que aparentemente implementa este comportamiento de “seleccionar nodo mientras que se mantiene presionado el botón derecho”.

Sin embargo, lo que funciona es anular WndProc en un control TreeView derivado y manejar el mensaje WM_RBUTTONDOWN . Pero tenga en cuenta que incluso establecer la propiedad SelectedNode en null no funciona aquí, ya que no se procesa hasta que Windows selecciona automáticamente el nodo como respuesta al clic con el botón derecho del mouse, sin importar lo que haga, debe evitar la base. TreeView control TreeView de recibir el mensaje WM_RBUTTONDOWN . Entonces, tienes un par de opciones para manejar esto:

  1. Simplemente puede cancelar el mensaje de clic derecho si realiza un rescate anticipado con una statement de return . Por supuesto, esto significa que no podrá manejar este evento en su controlador MouseDown , ¡porque en realidad nunca se pasa al control! Por lo tanto, si desea mostrar un menú contextual emergente, es probable que esto no le funcione.

     public class NewTreeView : System.Windows.Forms.TreeView { protected override void WndProc(ref System.Windows.Forms.Message m) { const int WM_RBUTTONDOWN = 0x204; if (m.Msg == WM_RBUTTONDOWN) { return; } base.WndProc(ref m); } } 
  2. Puede mostrar su menú contextual en el método WndProc reemplazado como respuesta al mensaje WM_RBUTTONDOWN y luego return del método sin permitir que la clase base maneje el mensaje. Esto hace exactamente lo mismo que la primera solución (impide que el evento de clic derecho haga que el nodo aparezca seleccionado), pero le permite mostrar un menú contextual (o hacer cualquier otra cosa que desee) siempre que haga clic derecho ocurre. Por supuesto, significa que todo el código relevante tendrá que estar contenido dentro de su subclase del control TreeView , no manejado en el código de UI de su formulario, que puede o no ser conveniente para usted.

     public class NewTreeView : System.Windows.Forms.TreeView { protected override void WndProc(ref System.Windows.Forms.Message m) { const int WM_RBUTTONDOWN = 0x204; if (m.Msg == WM_RBUTTONDOWN) { //Create and show a context menu var myContextMenu = new ContextMenuStrip(); myContextMenu.Items.Add("First Item"); myContextMenu.Items.Add("Second Item"); return; } base.WndProc(ref m); } } 
  3. Puede generar su propio evento RightMouseClick de su clase TreeView personalizada como respuesta al mensaje WM_RBUTTONDOWN , que luego puede manejar como desee desde el código de UI de su formulario. Al no pasar el mensaje WM_RBUTTONDOWN a la clase de control TreeView base, esto logra el mismo objective que las dos sugerencias anteriores, pero le permite controlar el evento de clic con el botón derecho en el código de UI de su formulario en lugar de tener que poner toda su lógica en El control WndProc .

     public class NewTreeView : System.Windows.Forms.TreeView { protected override void WndProc(ref System.Windows.Forms.Message m) { const int WM_RBUTTONDOWN = 0x204; if (m.Msg == WM_RBUTTONDOWN) { //Raise your custom event OnRightMouseClick(new EventArgs()); return; } base.WndProc(ref m); } } 

prueba esto

  void treeView1_MouseDown(object sender, MouseEventArgs e) { TreeViewHitTestInfo h = treeView1.HitTest(e.Location); if (h.Location != TreeViewHitTestLocations.Label && h.Location!= TreeViewHitTestLocations.None ) { treeView1.SelectedNode = null; } } 

He encontrado otro método para evitar que el nodo se destaque cuando el usuario no hace clic en el nodo, y solo configuro el BackColor y ForeColor para cada nodo al agregarlo al árbol

 newNode.BackColor = treeview1.BackColor; newNode.ForeColor = treeview1.ForeColor; treeview1.Nodes.Add(newNode); 

Luego, en el evento MouseDown, establezca la propiedad SelectedNode como sigue

  private void treeView1_MouseDown(object sender, MouseEventArgs e) { TreeNode Node = treeView1.GetNodeAt(e.Location); if (Node != null && Node.Bounds.Contains(e.Location)) treeView1.SelectedNode = Node; else treeView1.SelectedNode = null; } 

Si le comprendo correctamente, no desea que se seleccione ningún nodo si el usuario hace clic en el espacio vacío dentro de TreeView. Podría lograrlo manejando el evento MouseDown del evento Tree y configurando la propiedad SelectedNode del árbol en TreeView.GetNodeAt (e.Location).