2012-04-06 15 views
6

He aprendido a usar TVirtualStringTree, y me pareció excelente. Tengo una lista personalizada no visual llamada PackedList que se completa con otra cadena. Y quiero mostrar todo el contenido de la lista en TVirtualStringTree en tiempo real. Así que puse un temporizador en la forma principal para actualizar HexLog (que es TVirtualStringTree) RootNodeCount cada 500 ms.TVirtualStringTree y vertical Scroll no funciona correctamente

Todos mis datos aparecen en el VirtualStringTree, y no tengo ningún problema de velocidad, muy agradable. Pero hay un problema con la barra de desplazamiento vertical. Cuando presiono Ctrl + Fin en el control para saltar al final de la lista, va a algún lugar en el medio. Del mismo modo, cuando arrastro la barra de desplazamiento hasta el final, no llega al final. Pero HexLog conoce el DataCount. ¿Por qué no salta hasta el final? Si presiono un par de veces para presionar Ctrl + END, llega al final.

Rutina de temporizador interno, quiero decir que HexLog salta al final de la lista por código. ¿Cómo puedo hacer esto y cómo manejar la barra de desplazamiento vertical correctamente?

procedure TMainForm.StatusUpdateTimerTimer(Sender: TObject); 
begin 
    if (FirpList.ComOperationCount > 0) and (PacketList.Items.Count <> FirpList.ComOperationCount) then 
    begin 
     HexLog.RootNodeCount := PacketList.Items.Count; 
    end; 
end; 

procedure TMainForm.HexLogMeasureItem(Sender: TBaseVirtualTree; 
    TargetCanvas: TCanvas; Node: PVirtualNode; var NodeHeight: Integer); 
begin 
    if Sender.MultiLine[Node] then 
    begin 
    TargetCanvas.Font := Sender.Font; 
    NodeHeight := HexLog.ComputeNodeHeight(TargetCanvas, Node, 1, FirpList.ComOperations[Node^.Parent^.Index].DataAsHexString(FAppSettings.HexLogColumnCharWidth) + #13#10); 
    end; 
end; 

Appearance of HexLog

sugerido respuesta por Tlama no funciona correctamente, consulte la imagen para obtener una explicación: TLama solution is not working

Ver que enlazan para una explicación detallada de imagen: http://i43.tinypic.com/1445thi.png

Respuesta

6

para saltar a las final del árbol, llame al ScrollIntoView(GetLast).

Para desplazarse a un nodo particular, el control debe sumar las alturas de todos los nodos anteriores para que pueda determinar la compensación adecuada.

Sus nodos tienen diferentes alturas. Si no está inicializando las alturas reales de los nodos en algún lugar, entonces el control usa la propiedad DefaultNodeHeight para cualquier nodo no inicializado. Parece que la altura es más corta que cualquier altura de nodo real en su árbol, por lo que el control termina calculando un desplazamiento que es más pequeño de lo esperado, y se desplaza allí en lugar de donde lo desea.

Asegúrese de que está manejando el evento OnMeasureItem, y que tiene la opción toVariableNodeHeight establecida en Options.MiscOptions. Si no lo hace, entonces el control solo usará la altura actualmente asignada para cada nodo, y usará la altura predeterminada para cualquier nodo no inicializado.

Puede obtener el comportamiento que informa aquí si asigna manualmente NodeHeight en lugar de toVariableNodeHeight y maneja OnMeasureItem.

+0

Hola Rob, tengo controlador en MeasureItem para calcular la Altura del niño MultiLine. toVariableNodeHeight no se configuró en MiscOptions. Lo hice verdadero y ahora ScrollIntoView() salta al final correctamente. Pero se desplaza ligeramente y tarda unos 2 segundos en llegar al final, lo que no es aceptable:/ –

+0

Lo más importante que llevaría tiempo calcular el desplazamiento del último nodo, además de calcular las alturas de todos los nodos nuevos, sería si la memoria caché de posición de nodo no era válida. Establezca un punto de interrupción en 'GetDisplayRect' y vea si está en el estado' tsUseCache' cuando llama a 'ScrollIntoView'. Cuando la memoria caché es válida, el árbol puede encontrar las ubicaciones de los nodos mucho más rápido, pero cambiar el número de nodos invalida la caché. El hilo de trabajo necesita tiempo para volver a validarlo. –

+0

(tsUseCache en FStates) condición en la función GetDisplayRect() devuelve falso cuando invoco ScrollIntoView(). ¿Qué debería hacer ahora? Para este proyecto, estaba usando el control RichEdit, debido a los problemas de velocidad que enfrentaba, cambié todo el diseño para usar VirtualStringTree.Ahora, de nuevo, estoy en el mismo punto:/De hecho, estoy enfrentando dificultades para comprender por qué necesito calcular la altura de los mensajes completos para saltar al final de la lista. Simplemente quiero mostrar los últimos mensajes al usuario cada 500 ms mientras la transacción de datos está activa. –

Cuestiones relacionadas