2010-07-04 11 views
15

El siguiente código se toma directamente de Microsoft en http://msdn.microsoft.com/en-us/library/system.windows.forms.treeview.aftercheck%28VS.80%29.aspx.Vista en árbol de winforms, problema de nodos secundarios de comprobación recursiva

// Updates all child tree nodes recursively. 
    private void CheckAllChildNodes(TreeNode treeNode, bool nodeChecked) 
    { 
    foreach (TreeNode node in treeNode.Nodes) 
    { 
    node.Checked = nodeChecked; 
    if (node.Nodes.Count > 0) 
    { 
    // If the current node has child nodes, call the CheckAllChildsNodes method recursively. 
    this.CheckAllChildNodes(node, nodeChecked); 
    } 
    } 
    } 

    // NOTE This code can be added to the BeforeCheck event handler instead of the AfterCheck event. 
    // After a tree node's Checked property is changed, all its child nodes are updated to the same value. 
    private void node_AfterCheck(object sender, TreeViewEventArgs e) 
    { 
    // The code only executes if the user caused the checked state to change. 
    if (e.Action != TreeViewAction.Unknown) 
    { 
    if (e.Node.Nodes.Count > 0) 
    { 
    /* Calls the CheckAllChildNodes method, passing in the current 
    Checked value of the TreeNode whose checked state changed. */ 
    this.CheckAllChildNodes(e.Node, e.Node.Checked); 
    } 
    } 
    } 

lo pones en una forma que contiene una vista de árbol y llamar node_AfterCheck en (sorpresa, sorpresa), el evento AfterCheck vista de árbol. Luego revisa o desmarca de manera recursiva los nodos secundarios en la vista de árbol.

Sin embargo, si realmente lo intenta y hace clic varias veces en la misma casilla de vista de árbol con la suficiente rapidez, los nodos secundarios terminan con su comprobación fuera de sincronización con el elemento primario. Probablemente necesite un par de niveles de niños con quizás 100 niños en total para que la actualización de la interfaz de usuario sea lo suficientemente lenta como para darse cuenta de que esto está sucediendo.

He intentado un par de cosas (como deshabilitar el control TreeView al principio de node_AfterCheck y volver a habilitarlo al final), pero el problema de falta de sincronización aún ocurre.

¿Alguna idea?

+0

He publicado mi solución en un tema hijo de éste: http://stackoverflow.com/questions/14699102/treeview-check-uncheck-all-child-items/23065225#23065225 –

Respuesta

30

La clase .NET TreeView personaliza en gran medida el manejo del mouse para el control nativo de Windows con el fin de sintetizar los eventos Antes/Después. Desafortunadamente, no lo entendieron del todo bien. Cuando comienzas a hacer clic rápido, generarás doble clic en los mensajes. El control nativo responde haciendo doble clic al alternar el estado marcado para el artículo, , sin indicarle al contenedor .NET. No obtendrá un evento Before/AfterCheck.

Es un error pero no lo arreglarán. La solución alternativa no es difícil; deberá evitar que el control nativo vea el evento de doble clic. Agregue una nueva clase a su proyecto y pegue el código que se muestra a continuación. Compilar. Suelte el nuevo control desde la parte superior de la caja de herramientas, reemplazando el existente.

using System; 
using System.Windows.Forms; 

class MyTreeView : TreeView { 
    protected override void WndProc(ref Message m) { 
     // Filter WM_LBUTTONDBLCLK 
     if (m.Msg != 0x203) base.WndProc(ref m); 
    } 
} 
+1

¿Por qué no lo arreglan? – Kamil

+0

@Kamil porque 'winforms' va a morir. Todos, tarde o temprano, cambiarán a 'WPF'. –

+3

Sí, la muerte inminente se ha predicho desde hace 7 años. –

Cuestiones relacionadas