2012-04-28 16 views
18

Vine a saber que al agregar TreeView.BeginUpdate evitará el parpadeo de treeview, pero cuando lo agregué a mi proyecto desaparecen todos los nodos de mi vista de árbol, ¿Puede algún cuerpo decirme por qué sucede, aquí está el fragmento de código donde usado TreeView.BeginUpdate y TreeView.EndUpdate¿parpadeo de árbol?

TreeNode treeNode = new TreeNode("Windows"); 
     treeView1.Nodes.Add(treeNode); 
     // 
     // Another node following the first node. 
     // 
     treeNode = new TreeNode("Linux"); 
     treeView1.Nodes.Add(treeNode); 
     // 
     // Create two child nodes and put them in an array. 
     // ... Add the third node, and specify these as its children. 
     // 
     TreeNode node2 = new TreeNode("C#"); 
     TreeNode node3 = new TreeNode("VB.NET"); 
     TreeNode[] array = new TreeNode[] { node2, node3 }; 
     // 
     // Final node. 
     // 
     treeNode = new TreeNode("Dot Net Perls", array); 
     treeView1.Nodes.Add(treeNode); 
+6

que primero no se ve bien - que está haciendo 'BeginUpdate' /' EndUpdate' dentro de un bucle - y peor aún, el 'EndUpdate' está anidado dentro de un cierto código condicional - que normalmente se esperaría ver algo que suprime las actualizaciones visuales que se envuelve alrededor de todo el conjunto de actualizaciones (según su segundo ejemplo) –

+0

a pesar del código cuestionable, parece que está tratando de remediar un síntoma del problema. ¿La verdadera pregunta es por qué empezaste a parpadear en primer lugar? o no hubo parpadeo? –

+0

si utilicé justo encima de la adición de nodos quiero decir (.Nodes.Add) será suficiente? – vettori

Respuesta

60

el inicio/EndUpdate() métodos eran no diseñado para eliminar el parpadeo. Obtener el parpadeo en EndUpdate() es inevitable, repinta el control. Fueron diseñados para acelerar la adición de una gran cantidad de nodos, que serán lentos por defecto ya que cada elemento causa un repintado. Hiciste mucho peor poniéndolos dentro del ciclo for, muévelos afuera para una mejora inmediata.

Probablemente sea suficiente para resolver su problema. Pero puedes hacerlo mejor, suprimir el parpadeo requiere doble buffering. La clase .NET TreeView anula la propiedad DoubleBuffered y oculta. Lo cual es un accidente histórico, el control nativo de Windows solo admite doble almacenamiento en búfer en Windows XP y versiones posteriores. .NET alguna vez fue compatible con Windows 2000 y Windows 98.

Eso ya no es relevante en estos días. Puede volver a colocarlo derivando su propia clase de TreeView. Agregue una nueva clase a su proyecto y pegue el código que se muestra a continuación. Compilar. Suelte el nuevo control de la parte superior de la caja de herramientas en su formulario, reemplazando el TreeView existente. El efecto es muy notable, particularmente cuando se desplaza.

using System; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

class BufferedTreeView : TreeView { 
    protected override void OnHandleCreated(EventArgs e) { 
     SendMessage(this.Handle, TVM_SETEXTENDEDSTYLE, (IntPtr)TVS_EX_DOUBLEBUFFER, (IntPtr)TVS_EX_DOUBLEBUFFER); 
     base.OnHandleCreated(e); 
    } 
    // Pinvoke: 
    private const int TVM_SETEXTENDEDSTYLE = 0x1100 + 44; 
    private const int TVM_GETEXTENDEDSTYLE = 0x1100 + 45; 
    private const int TVS_EX_DOUBLEBUFFER = 0x0004; 
    [DllImport("user32.dll")] 
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 
} 
+5

MSDN sugiere que su uso de TVM_SETEXTENDEDSTYLE no es del todo correcto; por http://msdn.microsoft.com/en-us/library/windows/desktop/bb773744(v=vs.85).aspx la WPARAM es una máscara y la LPARAM es la bandera. Así que omita obtener el estilo anterior y simplemente envíe SendMessage (this.Handle, TVM_SETEXTENDEDSTYLE, (IntPtr) TVS_EX_DOUBLEBUFFER, (IntPtr) TVS_EX_DOUBLEBUFFER); – EricLaw

+0

Ugh, de hecho. Estoy usando una copia anterior de la biblioteca de MSDN que documenta esto mal. Gracias por el correcto! –

Cuestiones relacionadas