2010-07-04 6 views
15

Il seguente codice viene preso direttamente da Microsoft allo http://msdn.microsoft.com/en-us/library/system.windows.forms.treeview.aftercheck%28VS.80%29.aspx.Wineview treeview, verificare in modo ricorsivo il problema dei nodi figlio

// 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 metti in una forma che contiene una vista ad albero e chiamare node_AfterCheck su (sorpresa, sorpresa), la vista ad albero evento AfterCheck. Quindi controlla o deseleziona in modo ricorsivo i nodi figlio sulla vista ad albero.

Tuttavia, se effettivamente lo si tenta e si fa clic più volte sulla stessa casella di controllo treeview abbastanza velocemente, i nodi figlio terminano con il controllo fuori sincrono con il genitore. Probabilmente hai bisogno di un paio di livelli di bambini con almeno 100 bambini in totale perché l'aggiornamento dell'interfaccia utente sia abbastanza lento da notare che questo accada.

Ho provato un paio di cose (come disabilitare il controllo treeview all'inizio di node_AfterCheck e riattivare alla fine), ma il problema di fuori sincrono si verifica ancora.

Qualche idea?

+0

ho postato la mia soluzione in un argomento figlio di quest'ultimo: http://stackoverflow.com/questions/14699102/treeview-check-uncheck-all-child-items/23065225#23065225 –

risposta

30

La classe .NET TreeView personalizza notevolmente la gestione del mouse per il controllo nativo di Windows al fine di sintetizzare gli eventi Prima/Dopo. Sfortunatamente, non hanno capito bene. Quando inizi a fare clic velocemente, genererai messaggi con doppio clic. Il controllo nativo risponde a un doppio clic attivando lo stato selezionato per l'elemento, senza dirlo al wrapper .NET su di esso. Non riceverai un evento Before/AfterCheck.

È un errore ma non lo risolveranno. La soluzione alternativa non è difficile, devi impedire al controllo nativo di vedere l'evento doppio clic. Aggiungi una nuova classe al tuo progetto e incolla il codice mostrato di seguito. Compilare. Rilascia il nuovo controllo dalla parte superiore della casella degli strumenti, sostituendo quello esistente.

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

Perché non lo risolveranno? – Kamil

+0

@Kamil perché 'winforms' sta per morire. Prima o poi tutti passeranno a 'WPF'. –

+3

Sì, la morte imminente è stata prevista già da 7 anni. –

Problemi correlati