2011-05-25 12 views
13

Así que tengo un TreeView en una aplicación de formulario de Windows C#. Lo que necesito es que algunos nodos estén "bloqueados" para que no puedan verificarse (o desmarcarse), según un parámetro.C#: Cómo evitar que la verificación TreeNode ocurra en un evento de doble clic

Lo que estoy haciendo ahora es lo siguiente:

private void tv_local_BeforeCheck(object sender, TreeViewCancelEventArgs e) { 
    TNode node = (TNode)e.Node; 
    //if a part node, cancel the action. 
    if (node.Type == "Part") { 
     e.Cancel = true;  
    } 
    //if a locked node, cancel the action 
    if (node.Locked == true) { 
     e.Cancel = true; 
    } 
} 

Este código funciona muy bien en un solo clic de la casilla de verificación, pero si los hace doble clic en una casilla de verificación de usuario, todavía comprueba/desactiva.

He intentado jugar con el evento nodeMouseDoubleClick, pero eso no quiere realmente ayudar, ya que no puedo cancelar el evento ...

¿Hay alguna idea por ahí cómo cancelar un evento de doble clic en un nodo ?. .. ¿O algo más? Gracias

+0

Se puede publicar la código para su controlador de eventos de DoubleClick? –

+0

No tengo nada escrito allí. No quiero que pase nada con un doble clic ... Si pudiera hacer e.Cancel = true, ese sería el código en el evento doubleclick – Toadums

+0

¿Estás seguro de que no hay controladores configurados en ningún otro lado? Acabo de intentar colocar una vista de árbol en un formulario y no puedo reproducir el problema (estoy usando VSTS2008) –

Respuesta

21

Esto es un error en el TreeView creo (http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/9d717ce0-ec6b-4758-a357-6bb55591f956/). Debe crear una subclase de la vista en árbol y deshabilitar el doble clic para corregirlo. De esta manera:

public class NoClickTree : TreeView 
    { 
     protected override void WndProc(ref Message m) 
     { 
      // Suppress WM_LBUTTONDBLCLK 
      if (m.Msg == 0x203) { m.Result = IntPtr.Zero; } 
      else base.WndProc(ref m); 
     }    
    }; 

Por supuesto, si usted hace esto usted ya no será capaz de utilizar la metáfora de doble clic en la vista de árbol para otras cosas (por ejemplo, haga doble clic en un nodo para poner en marcha una página de propiedades , o algo).

+0

Había visto esta solución antes, pero no pude encontrar la manera de hacerlo funcionar. No me di cuenta de que tenía que crear una nueva clase y extender la clase treeview. ¡¡Gracias!! – Toadums

+1

Recuerde que debe inicializar su vista de árbol como 'NoClickTree' en el archivo' Form1.Designer.cs', no en 'Form1.cs', como se explica aquí [http://stackoverflow.com/a/14758596/1677209) – T30

+0

¡¡¡Estupendo !!! ¡Este error ha sido un dolor de cabeza por un tiempo! (Para mí, al menos) –

0

Intente extender la clase TreeNode y agregue una propiedad booleana que mantenga el estado checked correcto. De esta forma, cuando alguien hace doble clic en un nodo, puede restablecer el estado comprobado del nodo al valor almacenado en la propiedad. Puede haber una solución más elegante, pero esto es lo mejor que se me ocurre.

1

lo he conseguido con el siguiente código, lo que impide la comprobación nodos raíz:

private void MyTreeView_MouseUp(object sender, MouseEventArgs e) 
{ 
    // HACK: avoid to check root nodes (mr) 
    var node = ((TreeView)sender).GetNodeAt(new Point(e.X, e.Y)); 
    if (node != null && node.Parent == null) 
    BeginInvoke(new MouseEventHandler(TreeView_MouseUpAsync), sender, e); 
} 

private void TreeView_MouseUpAsync(object sender, MouseEventArgs e) 
{ 
    if (IsDisposed) 
     return; 

    var node = ((TreeView)sender).GetNodeAt(new Point(e.X, e.Y)); 
    node.Checked = false; 
} 
4

Si desea que su doble clic para cambiar realmente la casilla de verificación a continuación, tratar:

protected override void WndProc(ref Message m) 
{ 
    // Filter WM_LBUTTONDBLCLK when we're showing check boxes 
    if (m.Msg == 0x203 && CheckBoxes) 
    { 
    // See if we're over the checkbox. If so then we'll handle the toggling of it ourselves. 
    int x = m.LParam.ToInt32() & 0xffff; 
    int y = (m.LParam.ToInt32() >> 16) & 0xffff; 
    TreeViewHitTestInfo hitTestInfo = HitTest(x, y); 

    if (hitTestInfo.Node != null && hitTestInfo.Location == TreeViewHitTestLocations.StateImage) 
    { 
     OnBeforeCheck(new TreeViewCancelEventArgs(hitTestInfo.Node, false, TreeViewAction.ByMouse)); 
     hitTestInfo.Node.Checked = !hitTestInfo.Node.Checked; 
     OnAfterCheck(new TreeViewEventArgs(hitTestInfo.Node, TreeViewAction.ByMouse)); 
     m.Result = IntPtr.Zero; 
     return; 
    } 
    } 

    base.WndProc(ref m); 
} 
+0

Utilicé su código y parece que funciona. Muchas gracias. – DonkeyMaster

+0

¡Funciona a la perfección! –

Cuestiones relacionadas