Difference between revisions of "VirtualTreeview Example for Lazarus/es"
Line 1: | Line 1: | ||
{{Example for VirtualTreeview on Lazarus}} | {{Example for VirtualTreeview on Lazarus}} | ||
+ | [[category:Castellano|V]][[category:Español|V]] | ||
− | Aqui hay algunos ejemplos acerca de como | + | Aqui hay algunos ejemplos acerca de como usar el control VirtualTreeview para Lazarus (probado en win32). La mayoría de estos ejemplos han sido recolectados de la web, escritos para delphi, y de los documentos o tutoriales por Philipp Frenzel y Mike Lischke. Los documentos o tutoriales pueden ser descargados desde http://www.soft-gems.net . Abajo, usted puede encontrar alguna forma rapida de como utilizar VirtualTreeview en Lazarus, no explicaciones detalladas. Para más explicaciones y otros métodos o funciones, obtenga los documentos oficiales y el tutorial. |
= Ejemplo Tree Listview basico con 3 columnas = | = Ejemplo Tree Listview basico con 3 columnas = | ||
Line 9: | Line 10: | ||
2. Arrastre un componente TVirtualStringTree (bajo la pagina Controles Visuales). | 2. Arrastre un componente TVirtualStringTree (bajo la pagina Controles Visuales). | ||
− | 3. Vaya al editor de | + | 3. Vaya al editor de código (oprima la tecla F12). Bajo la sentencia ''Uses'' agregue una unidad - escriba VirtualTrees (si no existe previamente, no confunda con la unidad VirtualStringTree). Se vera de forma igual o similar a : |
− | <delphi>uses | + | <delphi> uses |
− | Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, | + | Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, VirtualStringTree, VirtualTrees;</delphi> |
− | |||
− | 4. Vaya al Diseñador de | + | 4. Vaya al Diseñador de Formularios (oprima la tecla F12). Seleccione el componente Virtual Tree. En el Inspector de Objetos haga clic en Nombre, escriba VST y oprima la tecla Enter (Return). Haga clic en Encabezado (expandalo) -> Columnas, haga clic en el pequeño botón, al lado de "0 elementos". Haga clic 3 veces en el botón agregar para agregar 3 columnas. No cierre esta ventana. |
− | 5. En la ventana para | + | 5. En la ventana para Edición de Columna, aparecerá la 3ra. columna como seleccionada. Vaya al Inspector de Objetos. Haga clic en Opciones (expandalo) -> y asigne coAllowClick como False. |
6. Haga clic en Texto. Escriba Column2. | 6. Haga clic en Texto. Escriba Column2. | ||
Line 22: | Line 22: | ||
7. Haga clic en ancho, escriba 100 y oprima la tecla Enter (Return). | 7. Haga clic en ancho, escriba 100 y oprima la tecla Enter (Return). | ||
− | 8. Vaya a la ventana para | + | 8. Vaya a la ventana para Edición de Columna, seleccione las columnas 1ra. y 2da., y asigne su propiedad como la de arriba (para el campo Texto, use nombres diferentes, ejemplo: Columna0, Columna1). |
− | 9. Cierre la ventana para | + | 9. Cierre la ventana para Edición de Columna. Seleccione el componente ''Virtual Tree'' en el formulario. En el Inspector de Objetos vaya a Encabezado -> Opciones (expandalo). Asigne coAllowClick como True. |
− | 10. | + | 10. Desplacese hacia abajo hasta Style, y asignelo como hsFlatButtons. |
− | 11. | + | 11. Desplacese hacia abajo hasta TreeOptions (expandalo) -> MiscOption (expandalo), y asigne toEditable como True. Asigne toGridExtensions como True. |
− | 12. | + | 12. Desplacese hacia abajo hasta SelectionOptions (expandalo) -> y asigne toExtendedFocus como True. Asigne toMultiSelect como True. En el Diseñador de Formularios cambie el tamaño del VST (componente Virtual) para para poder visualizar todas las columnas, en caso de que sea necesario. |
− | 13. Ahora, para agregar 3 botones en la forma. Arrastrelos desde la paleta de componentes - Pagina | + | 13. Ahora, para agregar 3 botones en la forma. Arrastrelos desde la paleta de componentes - Pagina Estándar (Etiquetados como "OK"). |
14. Haga clic en Button1, en el Inspector de Objetos cambie Titulo a "AddRoot". Haga clic en el Button2, cambie el titulo a "AddChild". Cambie el titulo de Button3 a "Delete". | 14. Haga clic en Button1, en el Inspector de Objetos cambie Titulo a "AddRoot". Haga clic en el Button2, cambie el titulo a "AddChild". Cambie el titulo de Button3 a "Delete". | ||
− | 15. Mantenga esto | + | 15. Mantenga esto aquí y vaya al editor de código (oprima la tecla F12). En el Editor de Código reemplace la linea: |
− | {$mode objfpc}{$H+} with {$MODE DELPHI} | + | <delphi> {$mode objfpc}{$H+} with {$MODE DELPHI}</delphi> |
− | 16. Bajo la sentencia "implementation" pegue las siguientes lineas de | + | 16. Bajo la sentencia "implementation" pegue las siguientes lineas de código: |
− | <delphi>type | + | <delphi> type |
− | + | PTreeData = ^TTreeData; | |
− | + | TTreeData = record | |
− | + | Column0: String; | |
− | + | Column1: String; | |
− | + | Column2: String; | |
− | + | end;</delphi> | |
− | 17. Vaya al Diseñador de Formas (oprima la tecla F12). Seleccione el control VST. Vaya al Inspector de Objetos, seleccione la pagina Eventos, | + | 17. Vaya al Diseñador de Formas (oprima la tecla F12). Seleccione el control VST. Vaya al Inspector de Objetos, seleccione la pagina Eventos, desplazese hasta el evento onChange. Haga doble clic en el control combobox. |
− | 18. | + | 18. Desplazese hasta el evento onFocusChanged. Haga doble clic y pegue el código siguiente: |
− | <delphi>procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; | + | <delphi> procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; |
Column: TColumnIndex); | Column: TColumnIndex); | ||
− | begin | + | begin |
VST.Refresh; | VST.Refresh; | ||
− | end;</delphi> | + | end;</delphi> |
− | 19. | + | 19. Desplacese hasta el evento onFreeNode. Haga doble clic y pegue el código siguiente: |
− | <delphi>procedure TForm1.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode); | + | <delphi> procedure TForm1.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode); |
− | var | + | var |
Data: PTreeData; | Data: PTreeData; | ||
− | begin | + | begin |
Data:=VST.GetNodeData(Node); | Data:=VST.GetNodeData(Node); | ||
if Assigned(Data) then begin | if Assigned(Data) then begin | ||
Line 70: | Line 70: | ||
Data^.Column2 := ''; | Data^.Column2 := ''; | ||
end; | end; | ||
− | end;</delphi> | + | end;</delphi> |
− | 20. | + | 20. Desplacese hasta el evento onGetNodeDataSize. Haga doble clic y pegue el código siguiente: |
− | <delphi>procedure TForm1.VSTGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer); | + | <delphi> procedure TForm1.VSTGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer); |
− | begin | + | begin |
NodeDataSize := SizeOf(TTreeData); | NodeDataSize := SizeOf(TTreeData); | ||
− | end;</delphi> | + | end;</delphi> |
− | 21. | + | 21. Desplacese hasta el evento onGetText. Haga doble clic y pegue el código siguiente: |
− | <delphi>procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; | + | <delphi> procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; |
Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString); | Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString); | ||
var | var | ||
Line 92: | Line 92: | ||
end;</delphi> | end;</delphi> | ||
− | 22. Oprima la tecla F12 para ir al Diseñador de Formas. Haga doble clic en el | + | 22. Oprima la tecla F12 para ir al Diseñador de Formas. Haga doble clic en el botón "AddRoot". Haga doble clic y pegue el código siguiente: |
− | <delphi>procedure TForm1.Button1Click(Sender: TObject); | + | <delphi> procedure TForm1.Button1Click(Sender: TObject); |
− | Var | + | Var |
Data: PTreeData; | Data: PTreeData; | ||
XNode: PVirtualNode; | XNode: PVirtualNode; | ||
Rand: Integer; | Rand: Integer; | ||
− | Begin | + | Begin |
Randomize; | Randomize; | ||
Rand := Random(99); | Rand := Random(99); | ||
Line 111: | Line 111: | ||
Data^.Column2:= 'Three ' + IntToStr(Rand - 10); | Data^.Column2:= 'Three ' + IntToStr(Rand - 10); | ||
End; | End; | ||
− | End;</delphi> | + | End;</delphi> |
− | 23. Oprima la tecla F9 para Ejecutar el proyecto y revisarlo. Haga clic en el | + | 23. Oprima la tecla F9 para Ejecutar el proyecto y revisarlo. Haga clic en el botón "AddRoot" para agregar un nodo. Si no hay problema alguno, el nodo sera agregado al control V.S.T. |
− | 24. Detenga la | + | 24. Detenga la ejecución del programa. En el Diseñador de Formularios haga doble clic en el botón titulado "AddChild". Haga doble clic y pegue el código siguiente: |
− | <delphi>procedure TForm1.Button2Click(Sender: TObject); | + | <delphi> procedure TForm1.Button2Click(Sender: TObject); |
− | var | + | var |
XNode: PVirtualNode; | XNode: PVirtualNode; | ||
Data: PTreeData; | Data: PTreeData; | ||
− | begin | + | begin |
if not Assigned(VST.FocusedNode) then | if not Assigned(VST.FocusedNode) then | ||
Exit; | Exit; | ||
Line 133: | Line 133: | ||
VST.Expanded[VST.FocusedNode]:=True; | VST.Expanded[VST.FocusedNode]:=True; | ||
− | end;</delphi> | + | end;</delphi> |
− | 25. En el Diseñador de | + | 25. En el Diseñador de Formularios haga doble clic en el botón titulado "Delete". Haga doble clic y pegue el código siguiente: |
− | <delphi>procedure TForm1.Button3Click(Sender: TObject); | + | <delphi> procedure TForm1.Button3Click(Sender: TObject); |
− | begin | + | begin |
VST.DeleteSelectedNodes; | VST.DeleteSelectedNodes; | ||
− | end;</delphi> | + | end;</delphi> |
26. Ejecute el proyecto, oprimiendo la tecla F9 para revisarlo. Haga varias pruebas, agregando algunos nodos principales, nodos hijos y eliminelos. | 26. Ejecute el proyecto, oprimiendo la tecla F9 para revisarlo. Haga varias pruebas, agregando algunos nodos principales, nodos hijos y eliminelos. | ||
− | 27. Intente editar un | + | 27. Intente editar un nodo. Seleccione un nodo y oprima la tecla F2, y escriba un nuevo valor. Si puede ver lo que esta escribiendo, entonces, el paso esta bien. De lo contrario, lea la sección siguiente titulada "Cuando la edición de celda no puede verse". |
− | 28. Para obtener que el V.S.T. muestre el nuevo valor capturado | + | 28. Para obtener que el V.S.T. muestre el nuevo valor capturado después de la edición, vaya al Diseñador de Formas, y seleccione V.S.T. Haga doble clic, en el ''combo'' del Inspector de Objetos -> Events -> OnNewText. |
− | Haga doble clic y pegue el | + | Haga doble clic y pegue el código siguiente: |
− | <delphi>procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode; | + | <delphi> procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode; |
Column: TColumnIndex; NewText: WideString); | Column: TColumnIndex; NewText: WideString); | ||
− | Var | + | Var |
Data: PTreeData; | Data: PTreeData; | ||
− | begin | + | begin |
Data := VST.GetNodeData(Node); | Data := VST.GetNodeData(Node); | ||
Case Column of | Case Column of | ||
Line 160: | Line 160: | ||
2: Data^.Column2:= NewText; | 2: Data^.Column2:= NewText; | ||
End; | End; | ||
− | end;</delphi> | + | end;</delphi> |
− | Hasta ahora, el ejemplo para uso | + | Hasta ahora, el ejemplo para uso básico, termina aquí. Usted podría arrastrar algunos botones adicionales en la forma para probar algunos de los comandos mencionados, mas adelante. El paso siguiente, podría ser, desplegar una casilla para marcar o ''checkbox'', imagen, color para tipo de fuente de texto, o agregar un ''combo'' al nodo. |
− | *Otra forma para agregar el nodo | + | *Otra forma para agregar el nodo raíz: |
− | <delphi>procedure TForm1.Button8Click(Sender: TObject); | + | <delphi> procedure TForm1.Button8Click(Sender: TObject); |
− | begin | + | begin |
with VST do | with VST do | ||
RootNodeCount:=RootNodeCount+1; | RootNodeCount:=RootNodeCount+1; | ||
− | end;</delphi> | + | end;</delphi> |
* Otra forma para agregar un nodo hijo: | * Otra forma para agregar un nodo hijo: | ||
− | <delphi>procedure TForm1.Button9Click(Sender: TObject); | + | <delphi> procedure TForm1.Button9Click(Sender: TObject); |
− | begin | + | begin |
if Assigned(VST.FocusedNode) Then | if Assigned(VST.FocusedNode) Then | ||
VST.ChildCount[VST.FocusedNode]:=VST.ChildCount[VST.FocusedNode]+1; | VST.ChildCount[VST.FocusedNode]:=VST.ChildCount[VST.FocusedNode]+1; | ||
− | end;</delphi> | + | end;</delphi> |
*Determinar y eliminar los nodos hijos de un nodo: | *Determinar y eliminar los nodos hijos de un nodo: | ||
− | <delphi>procedure TForm1.Button4Click(Sender: TObject); | + | <delphi> procedure TForm1.Button4Click(Sender: TObject); |
− | Var | + | Var |
c: Integer; | c: Integer; | ||
− | begin | + | begin |
if not Assigned(VST.FocusedNode) then | if not Assigned(VST.FocusedNode) then | ||
Exit; | Exit; | ||
Line 194: | Line 194: | ||
ShowMessage('Number of deleted child:' + #13#10 + IntToStr(c)); | ShowMessage('Number of deleted child:' + #13#10 + IntToStr(c)); | ||
End; | End; | ||
− | end;</delphi> | + | end;</delphi> |
* Eliminar un nodo: | * Eliminar un nodo: | ||
− | <delphi>procedure TForm1.Button5Click(Sender: TObject); | + | <delphi> procedure TForm1.Button5Click(Sender: TObject); |
− | begin | + | begin |
− | {VST.Clear; //Delete All Nodes} | + | {VST.Clear; //Delete All Nodes} |
if not Assigned(VST.FocusedNode) then | if not Assigned(VST.FocusedNode) then | ||
Exit; | Exit; | ||
VST.DeleteNode(VST.FocusedNode); | VST.DeleteNode(VST.FocusedNode); | ||
− | end;</delphi> | + | end;</delphi> |
* Buscar y seleccionar un nodo: | * Buscar y seleccionar un nodo: | ||
− | <delphi>procedure TForm1.Button6Click(Sender: TObject); | + | <delphi> procedure TForm1.Button6Click(Sender: TObject); |
− | + | var | |
XNode: PVirtualNode; | XNode: PVirtualNode; | ||
Data: PTreeData; | Data: PTreeData; | ||
− | begin | + | begin |
XNode:= VST.GetFirst; | XNode:= VST.GetFirst; | ||
Line 227: | Line 227: | ||
XNode:= VST.GetNextSibling(XNode); | XNode:= VST.GetNextSibling(XNode); | ||
end; | end; | ||
− | end;</delphi> | + | end;</delphi> |
* Determinar el nodo padre de un nodo: | * Determinar el nodo padre de un nodo: | ||
− | <delphi>procedure TForm1.Button13Click(Sender: TObject); | + | <delphi> procedure TForm1.Button13Click(Sender: TObject); |
− | var | + | var |
XNode: PVirtualNode; | XNode: PVirtualNode; | ||
− | begin | + | begin |
if not Assigned(VST.FocusedNode) then | if not Assigned(VST.FocusedNode) then | ||
Exit; | Exit; | ||
Line 245: | Line 245: | ||
VST.Refresh; | VST.Refresh; | ||
VST.SetFocus; | VST.SetFocus; | ||
− | end;</delphi> | + | end;</delphi> |
* Buscar todos los nodos: | * Buscar todos los nodos: | ||
− | <delphi>procedure TForm1.Button7Click(Sender: TObject); | + | <delphi> procedure TForm1.Button7Click(Sender: TObject); |
− | Var | + | Var |
XNode: PVirtualNode; | XNode: PVirtualNode; | ||
Data: PTreeData; | Data: PTreeData; | ||
− | begin | + | begin |
If VST.GetFirst = nil then Exit; | If VST.GetFirst = nil then Exit; | ||
XNode:=nil; | XNode:=nil; | ||
Line 265: | Line 265: | ||
End; | End; | ||
Until XNode = VST.GetLast(); | Until XNode = VST.GetLast(); | ||
− | end;</delphi> | + | end;</delphi> |
* Buscar el nodo siguiente: | * Buscar el nodo siguiente: | ||
− | <delphi>procedure TForm1.Button8Click(Sender: TObject); | + | <delphi> procedure TForm1.Button8Click(Sender: TObject); |
− | var | + | var |
XNode: PVirtualNode; | XNode: PVirtualNode; | ||
Data: PTreeData; | Data: PTreeData; | ||
− | begin | + | begin |
if not Assigned(VST.GetFirst) then | if not Assigned(VST.GetFirst) then | ||
Exit | Exit | ||
Line 294: | Line 294: | ||
end; | end; | ||
until XNode = VST.GetLast; | until XNode = VST.GetLast; | ||
− | end;</delphi> | + | end;</delphi> |
* Insertar Nodo: | * Insertar Nodo: | ||
− | <delphi>procedure TForm1.Button12Click(Sender: TObject); | + | <delphi> procedure TForm1.Button12Click(Sender: TObject); |
− | var | + | var |
XNode: PVirtualNode; | XNode: PVirtualNode; | ||
− | begin | + | begin |
If Assigned(VST.FocusedNode) then | If Assigned(VST.FocusedNode) then | ||
begin | begin | ||
Line 309: | Line 309: | ||
VST.Refresh; | VST.Refresh; | ||
end; | end; | ||
− | end;</delphi> | + | end;</delphi> |
* Asignar la altura de un nodo: | * Asignar la altura de un nodo: | ||
− | <delphi>procedure TForm1.Button14Click(Sender: TObject); | + | <delphi> procedure TForm1.Button14Click(Sender: TObject); |
− | begin | + | begin |
If Assigned(VST.FocusedNode) then | If Assigned(VST.FocusedNode) then | ||
VST.NodeHeight[VST.FocusedNode] := 32; | VST.NodeHeight[VST.FocusedNode] := 32; | ||
− | end;</delphi> | + | end;</delphi> |
* Guardar y Cargar: | * Guardar y Cargar: | ||
− | El arbol simple (sin columnas), puede ser guardado y recargado con: | + | El arbol simple (sin columnas), puede ser guardado y recargado con: |
− | <delphi> | + | <delphi> VST.SaveToFile('filename.dat'); |
− | VST.SaveToFile('filename.dat'); | + | VST.LoadFromFile('filename.dat');</delphi> |
− | VST.LoadFromFile('filename.dat'); | ||
− | </delphi> | ||
− | Para guardar y cargar el ejemplo mencionado arriba, coloque 2 botones en la forma, cambie el titulo de un boton a "Guardar", y el titulo del otro boton a "Cargar". Seleccione el V.S.T., En el Inspector de Objetos -> TreeOptions -> StringOptions. Asegurese, que el valor de la propiedad toSaveCaptions este asignada como True. Vaya a la pagina del Inspector de Eventos Events. Desplazece hasta OnLoadNode, haga doble cilc y pegue el codigo siguiente: | + | Para guardar y cargar el ejemplo mencionado arriba, coloque 2 botones en la forma, cambie el titulo de un boton a "Guardar", y el titulo del otro boton a "Cargar". Seleccione el V.S.T., En el Inspector de Objetos -> TreeOptions -> StringOptions. Asegurese, que el valor de la propiedad toSaveCaptions este asignada como True. Vaya a la pagina del Inspector de Eventos Events. Desplazece hasta OnLoadNode, haga doble cilc y pegue el codigo siguiente: |
− | <delphi>procedure TForm1.VSTLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode; | + | <delphi> procedure TForm1.VSTLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode; |
Stream: TStream); | Stream: TStream); | ||
− | Var | + | Var |
Data: PTreeData; | Data: PTreeData; | ||
Len: Integer; | Len: Integer; | ||
− | begin | + | begin |
Data := VST.GetNodeData(Node); | Data := VST.GetNodeData(Node); | ||
Stream.read(Len, SizeOf(Len)); | Stream.read(Len, SizeOf(Len)); | ||
Line 348: | Line 346: | ||
SetLength(Data^.Column2, Len); | SetLength(Data^.Column2, Len); | ||
Stream.read(PChar(Data^.Column2)^, Len); | Stream.read(PChar(Data^.Column2)^, Len); | ||
− | end;</delphi> | + | end;</delphi> |
− | Otra vez, en la pagina Events del Inspector de Objetos, desplazece hasta OnSaveNode, haga doble cilc y pegue el codigo siguiente: | + | Otra vez, en la pagina Events del Inspector de Objetos, desplazece hasta OnSaveNode, haga doble cilc y pegue el codigo siguiente: |
− | <delphi> | + | <delphi> procedure TForm1.VSTSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode; |
− | procedure TForm1.VSTSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode; | ||
Stream: TStream); | Stream: TStream); | ||
− | Var | + | Var |
Data: PTreeData; | Data: PTreeData; | ||
Len: Integer; | Len: Integer; | ||
− | begin | + | begin |
Data := VST.GetNodeData(Node); | Data := VST.GetNodeData(Node); | ||
Len := Length(Data^.Column0); | Len := Length(Data^.Column0); | ||
Line 371: | Line 368: | ||
Stream.write(Len, SizeOf(Len)); | Stream.write(Len, SizeOf(Len)); | ||
Stream.write(PChar(Data^.Column2)^, Len); | Stream.write(PChar(Data^.Column2)^, Len); | ||
− | end;</delphi> | + | end;</delphi> |
− | En el Diseñador de | + | En el Diseñador de Formularios, haga doble clic en el boton titulado "Save" o "Guargar", y pegue el codigo siguiente: |
− | y pegue el codigo siguiente: | ||
− | <delphi>procedure TForm1.Button10Click(Sender: TObject); | + | <delphi> procedure TForm1.Button10Click(Sender: TObject); |
− | begin | + | begin |
VST.SaveToFile('C:\vst.dat'); | VST.SaveToFile('C:\vst.dat'); | ||
− | end;</delphi> | + | end;</delphi> |
− | En el Diseñador de | + | En el Diseñador de Formularios, haga doble clic en el boton titulado "Load" o "Cargar", y pegue el codigo siguiente: |
− | y pegue el codigo siguiente: | ||
<delphi> | <delphi> | ||
Line 391: | Line 386: | ||
</delphi> | </delphi> | ||
− | Ahora, haga pruebas, para guardar y volver a cargar el arbol. | + | Ahora, haga pruebas, para guardar y volver a cargar el arbol. |
*Problema de desplazamiento | *Problema de desplazamiento | ||
− | El encabezado de control vistaarbol desaparece parcialmente o completamente al desplazarse. No pude encontrar una buena solucion a esto. Una forma de sobrepasar esto, es asignar la altura del encabezado a 0, y utilizar una etiqueta generica para las columnas, y todas las columnas estan visibles sin desplazamiento horizontal. O, la altura del encabezado puede ser asignada un valor mas alto, entre 25 o 30. El metodo VST.Refresh puede ser asignado al evento OnScroll. | + | El encabezado de control vistaarbol desaparece parcialmente o completamente al desplazarse. No pude encontrar una buena solucion a esto. Una forma de sobrepasar esto, es asignar la altura del encabezado a 0, y utilizar una etiqueta generica para las columnas, y todas las columnas estan visibles sin desplazamiento horizontal. O, la altura del encabezado puede ser asignada un valor mas alto, entre 25 o 30. El metodo VST.Refresh puede ser asignado al evento OnScroll. |
*Cambiar el tamaño de las columnas | *Cambiar el tamaño de las columnas | ||
− | No fue posible cambiar el tamaño de las columnas, arrastrando el raton en el encabezado del V.S.T. Tal vez, sea debido al "bug" del encabezado, o tal vez, omiti algo. En caso de que la causa haya sido el encabezado, tal vez sea corregido en la siguiente version de Lazarus. Puede ver este enlace: http://bugs.freepascal.org/view.php?id=11209<br> | + | No fue posible cambiar el tamaño de las columnas, arrastrando el raton en el encabezado del V.S.T. Tal vez, sea debido al "bug" del encabezado, o tal vez, omiti algo. En caso de que la causa haya sido el encabezado, tal vez sea corregido en la siguiente version de Lazarus. Puede ver este enlace: http://bugs.freepascal.org/view.php?id=11209<br> |
− | De cualquier forma, es posible cambiar el tamaño de las columnas por medio de codigo. Cuando presione mantenga presionado el boton derecho del raton, y gire la rueda arriba, el ancho de la columna seleccionada se incrementa, y manteniendo presionado abajo, el boton derecho del raton y girando hacia abjo la rueda del raton, podra decrementar el ancho de la columna seleccionada. Para hacer esto:<br> | + | De cualquier forma, es posible cambiar el tamaño de las columnas por medio de codigo. Cuando presione mantenga presionado el boton derecho del raton, y gire la rueda arriba, el ancho de la columna seleccionada se incrementa, y manteniendo presionado abajo, el boton derecho del raton y girando hacia abjo la rueda del raton, podra decrementar el ancho de la columna seleccionada. Para hacer esto:<br> |
1. Agregue una variable en el editor de codigo llamada como CurCol: Integer; Se vera como esto: | 1. Agregue una variable en el editor de codigo llamada como CurCol: Integer; Se vera como esto: | ||
− | <delphi> | + | <delphi> var |
− | var | ||
Form1: TForm1; | Form1: TForm1; | ||
CurCol: Integer; // <- Agregue solo esta linea. | CurCol: Integer; // <- Agregue solo esta linea. | ||
− | implementation | + | implementation |
− | { TForm1 } | + | { TForm1 }</delphi> |
− | |||
− | </delphi> | ||
2. En el diseñador de Formas, haga doble clic en la forma para generar un procedimiento para el evento OnCreate. En el procedimiento OnCreate, escriba Form1.OnMouseWheelUp:= y presione Ctrl+Shift+C, esto completara el codigoy hara el esqueleto del procedimiento para el evento MouseWheelUp. ahora, regrese al procedimiento TForm1.FormCreate(Sender: TObject); Y agregue otro procedimiento, esta vez para el evento MouseWheelDown. Escriba Form1.OnMouseWheelDown:= y oprima la combinacion de teclas Ctrl+Shift+C, para generar el procedimiento para el evento MouseWheelDown. El procedimiento FormCreate se mira asi: | 2. En el diseñador de Formas, haga doble clic en la forma para generar un procedimiento para el evento OnCreate. En el procedimiento OnCreate, escriba Form1.OnMouseWheelUp:= y presione Ctrl+Shift+C, esto completara el codigoy hara el esqueleto del procedimiento para el evento MouseWheelUp. ahora, regrese al procedimiento TForm1.FormCreate(Sender: TObject); Y agregue otro procedimiento, esta vez para el evento MouseWheelDown. Escriba Form1.OnMouseWheelDown:= y oprima la combinacion de teclas Ctrl+Shift+C, para generar el procedimiento para el evento MouseWheelDown. El procedimiento FormCreate se mira asi: | ||
− | <delphi> | + | <delphi> procedure TForm1.FormCreate(Sender: TObject); |
− | procedure TForm1.FormCreate(Sender: TObject); | + | begin |
− | begin | ||
Form1.OnMouseWheelUp:=@Form1MouseWheelUp; | Form1.OnMouseWheelUp:=@Form1MouseWheelUp; | ||
Form1.OnMouseWheelDown:=@Form1MouseWheelDown; | Form1.OnMouseWheelDown:=@Form1MouseWheelDown; | ||
− | end;</delphi> | + | end;</delphi> |
3. Capture el procedimiento para el evento TForm1.Form1MouseWheelUp procedure como: | 3. Capture el procedimiento para el evento TForm1.Form1MouseWheelUp procedure como: | ||
− | <delphi> | + | <delphi> procedure TForm1.Form1MouseWheelUp(Sender: TObject; Shift: TShiftState; |
− | procedure TForm1.Form1MouseWheelUp(Sender: TObject; Shift: TShiftState; | ||
MousePos: TPoint; var Handled: Boolean); | MousePos: TPoint; var Handled: Boolean); | ||
− | begin | + | begin |
If VST.Focused then | If VST.Focused then | ||
if ssRight in Shift then | if ssRight in Shift then | ||
VST.Header.Columns[CurCol].Width:= VST.Header.Columns[CurCol].Width + 10; | VST.Header.Columns[CurCol].Width:= VST.Header.Columns[CurCol].Width + 10; | ||
− | end; | + | end;</delphi> |
− | </delphi> | ||
4. Capture el procedimiento para el evento TForm1.Form1MouseWheelDown procedure como: | 4. Capture el procedimiento para el evento TForm1.Form1MouseWheelDown procedure como: | ||
− | <delphi> | + | <delphi> procedure TForm1.Form1MouseWheelDown(Sender: TObject; Shift: TShiftState; |
− | procedure TForm1.Form1MouseWheelDown(Sender: TObject; Shift: TShiftState; | ||
MousePos: TPoint; var Handled: Boolean); | MousePos: TPoint; var Handled: Boolean); | ||
− | begin | + | begin |
If VST.Focused then | If VST.Focused then | ||
if ssRight in Shift then | if ssRight in Shift then | ||
VST.Header.Columns[CurCol].Width:= VST.Header.Columns[CurCol].Width - 10; | VST.Header.Columns[CurCol].Width:= VST.Header.Columns[CurCol].Width - 10; | ||
− | end; | + | end;</delphi> |
− | </delphi> | ||
5. Vaya al Diseñador de Formas (puede oprimir F12), seleccione el V.S.T., En la pagina Events, del Inspector de Objetos, desplazece hasta OnFocusChanged, haga doble clic y pegue el codigo siguiente: | 5. Vaya al Diseñador de Formas (puede oprimir F12), seleccione el V.S.T., En la pagina Events, del Inspector de Objetos, desplazece hasta OnFocusChanged, haga doble clic y pegue el codigo siguiente: | ||
− | <delphi>procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree; | + | <delphi> procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree; |
Node: PVirtualNode; Column: TColumnIndex); | Node: PVirtualNode; Column: TColumnIndex); | ||
− | begin | + | begin |
CurCol:=Column; | CurCol:=Column; | ||
− | end;</delphi> | + | end;</delphi> |
+ | |||
+ | Cuando ejecute el programa, haga clic en una columna, despues mantenga presionado abajo, el boton derecho del raton, y gire la rueda arriba, para incrementar el ancho. Gire la rueda abajo decrementar los valores mencionados. | ||
− | + | Podria modificar los procedimientos anteriores, para ajustar un poco el resultado, si es necesario. O, agregar algun evento para el teclado, con algo como "if (key=187) and (ssShift in Shift) then" para utilizar la combinacion de teclas Shift + "+". | |
− | Podria modificar los procedimientos anteriores, para ajustar un poco el resultado, si es necesario. O, agregar algun evento para el teclado, con algo como "if (key=187) and (ssShift in Shift) then" para utilizar la combinacion de teclas Shift + "+". | ||
=Checkbox= | =Checkbox= | ||
− | En el Diseñador de Formas seleccione el control V.S.T. Vaya: | + | En el Diseñador de Formas seleccione el control V.S.T. Vaya: |
+ | |||
#Object Inspector -> Properties -> CheckImageKind y seleccione ckDarkCheck. | #Object Inspector -> Properties -> CheckImageKind y seleccione ckDarkCheck. | ||
− | #Object Inspector -> Properties -> TreeOptions -> MiscOptions -> toCheckSupport y asignelo como True. | + | #Object Inspector -> Properties -> TreeOptions -> MiscOptions -> toCheckSupport y asignelo como True. |
− | Ahora, cambie a la pagina de Events. | + | |
+ | Ahora, cambie a la pagina de Events. | ||
+ | |||
*Scroll to OnInitNode. Double click and paste the followings: | *Scroll to OnInitNode. Double click and paste the followings: | ||
− | <delphi>procedure TForm1.VSTInitNode(Sender: TBaseVirtualTree; ParentNode, | + | <delphi> procedure TForm1.VSTInitNode(Sender: TBaseVirtualTree; ParentNode, |
Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates); | Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates); | ||
− | Var | + | Var |
Level: Integer; | Level: Integer; | ||
− | begin | + | begin |
Level := VST.GetNodeLevel(Node); | Level := VST.GetNodeLevel(Node); | ||
if Level = 0 then | if Level = 0 then | ||
Line 487: | Line 478: | ||
if Level = 3 then | if Level = 3 then | ||
Node.CheckType:=ctButton; | Node.CheckType:=ctButton; | ||
− | end;</delphi> | + | end;</delphi> |
− | Run the program, add rootnode and child then child of the child, and check if you can check and uncheck properly. If not, close the program. Go to the Object Inspector's Events tab. | + | |
+ | Run the program, add rootnode and child then child of the child, and check if you can check and uncheck properly. If not, close the program. Go to the Object Inspector's Events tab. | ||
*Scroll to OnChecked, double click and paste: | *Scroll to OnChecked, double click and paste: | ||
− | <delphi>procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode); | + | <delphi> procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode); |
− | begin | + | begin |
vst.Refresh; | vst.Refresh; | ||
− | end;</delphi> | + | end;</delphi> |
*Scroll to OnChecking, double click and paste: | *Scroll to OnChecking, double click and paste: | ||
− | <delphi>procedure TForm1.VSTChecking(Sender: TBaseVirtualTree; Node: PVirtualNode; | + | <delphi> procedure TForm1.VSTChecking(Sender: TBaseVirtualTree; Node: PVirtualNode; |
− | + | var NewState: TCheckState; var Allowed: Boolean); | |
− | begin | + | begin |
− | + | VST.Refresh; | |
− | end;</delphi> | + | end;</delphi> |
− | Hope now it is ok. To determine checkbox state use like:<BR> | + | |
+ | Hope now it is ok. To determine checkbox state use like:<BR> | ||
− | If XNode.CheckState = csCheckedNormal then | + | <delphi> If XNode.CheckState = csCheckedNormal then ShowMessage('Checked.');</delphi> |
− | ShowMessage('Checked.');< | ||
Other states are:<br> | Other states are:<br> | ||
− | <delphi>csUncheckedNormal = unchecked and not pressed | + | <delphi> csUncheckedNormal = unchecked and not pressed |
− | csUncheckedPressed = unchecked and pressed | + | csUncheckedPressed = unchecked and pressed |
− | csCheckedNormal = checked and not pressed | + | csCheckedNormal = checked and not pressed |
− | csCheckedPressed = checked and pressed | + | csCheckedPressed = checked and pressed |
− | csMixedNormal = 3-state check box and not pressed | + | csMixedNormal = 3-state check box and not pressed |
− | csMixedPressed = 3-state check box and pressed</delphi> | + | csMixedPressed = 3-state check box and pressed</delphi> |
Other types are:<br> | Other types are:<br> | ||
Line 589: | Line 581: | ||
*Bellow there is an unit file named combo. Copy that unit and save as combo.pas inside the project directory. Under your program's uses clause add combo. So it may look like: | *Bellow there is an unit file named combo. Copy that unit and save as combo.pas inside the project directory. Under your program's uses clause add combo. So it may look like: | ||
− | <delphi>uses | + | <delphi> uses |
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, | Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, | ||
VirtualStringTree, VirtualTrees, combo;</delphi> | VirtualStringTree, VirtualTrees, combo;</delphi> | ||
*The combo.pas unit | *The combo.pas unit | ||
− | <delphi>unit combo; | + | <delphi> unit combo; |
− | {$mode delphi} | + | {$mode delphi} |
− | interface | + | interface |
− | uses | + | uses |
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, | Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, | ||
VirtualStringTree, VirtualTrees, messages, windows, StdCtrls; | VirtualStringTree, VirtualTrees, messages, windows, StdCtrls; | ||
− | type | + | type |
TStringEditLink = class(TInterfacedObject, IVTEditLink) | TStringEditLink = class(TInterfacedObject, IVTEditLink) | ||
private | private | ||
Line 624: | Line 616: | ||
end; | end; | ||
− | implementation | + | implementation |
− | destructor TStringEditLink.Destroy; | + | destructor TStringEditLink.Destroy; |
− | begin | + | begin |
FEdit.Free; | FEdit.Free; | ||
inherited; | inherited; | ||
− | end; | + | end; |
− | procedure TStringEditLink.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); | + | procedure TStringEditLink.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); |
− | begin | + | begin |
case Key of | case Key of | ||
VK_ESCAPE: | VK_ESCAPE: | ||
Line 649: | Line 641: | ||
end; | end; | ||
End; //case | End; //case | ||
− | end; | + | end; |
− | function TStringEditLink.BeginEdit: Boolean; | + | function TStringEditLink.BeginEdit: Boolean; |
− | begin | + | begin |
Result := True; | Result := True; | ||
//FEdit.Height:=(FTree.DefaultNodeHeight - 1); //Needed for editbox. Not combo | //FEdit.Height:=(FTree.DefaultNodeHeight - 1); //Needed for editbox. Not combo | ||
Line 658: | Line 650: | ||
TComboBox(FEdit).DroppedDown:=True; | TComboBox(FEdit).DroppedDown:=True; | ||
FEdit.SetFocus; | FEdit.SetFocus; | ||
− | end; | + | end; |
− | function TStringEditLink.CancelEdit: Boolean; | + | function TStringEditLink.CancelEdit: Boolean; |
− | begin | + | begin |
Result := True; | Result := True; | ||
FEdit.Hide; | FEdit.Hide; | ||
− | end; | + | end; |
− | function TStringEditLink.EndEdit: Boolean; | + | function TStringEditLink.EndEdit: Boolean; |
− | var | + | var |
S: WideString; | S: WideString; | ||
− | begin | + | begin |
Result := True; | Result := True; | ||
S:= TComboBox(FEdit).Text; | S:= TComboBox(FEdit).Text; | ||
Line 677: | Line 669: | ||
FEdit.Hide; | FEdit.Hide; | ||
FTree.SetFocus; | FTree.SetFocus; | ||
− | end; | + | end; |
− | function TStringEditLink.GetBounds: TRect; | + | function TStringEditLink.GetBounds: TRect; |
− | begin | + | begin |
Result := FEdit.BoundsRect; | Result := FEdit.BoundsRect; | ||
− | end; | + | end; |
− | function TStringEditLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; | + | function TStringEditLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; |
− | begin | + | begin |
Result := True; | Result := True; | ||
FTree := Tree as TVirtualStringTree; | FTree := Tree as TVirtualStringTree; | ||
Line 704: | Line 696: | ||
OnKeyDown := EditKeyDown; | OnKeyDown := EditKeyDown; | ||
end; | end; | ||
− | end; | + | end; |
− | procedure TStringEditLink.ProcessMessage(var Message: TMessage); | + | procedure TStringEditLink.ProcessMessage(var Message: TMessage); |
− | begin | + | begin |
FEdit.WindowProc(Message); | FEdit.WindowProc(Message); | ||
− | end; | + | end; |
− | procedure TStringEditLink.SetBounds(R: TRect); | + | procedure TStringEditLink.SetBounds(R: TRect); |
− | var | + | var |
Dummy: Integer; | Dummy: Integer; | ||
− | begin | + | begin |
FTree.Header.Columns.GetColumnBounds(FColumn, Dummy, R.Right); | FTree.Header.Columns.GetColumnBounds(FColumn, Dummy, R.Right); | ||
FEdit.BoundsRect := R; | FEdit.BoundsRect := R; | ||
− | end; | + | end; |
− | End.</delphi> | + | End.</delphi> |
*After saving the file, on the Form Designer select VST and on Object Inspector's Properties, scroll to TreeOptions -> MiscOptions, set toEditable to True. Then get to TreeOptions -> SelectionOptions, set toExtendedFocus to True. | *After saving the file, on the Form Designer select VST and on Object Inspector's Properties, scroll to TreeOptions -> MiscOptions, set toEditable to True. Then get to TreeOptions -> SelectionOptions, set toExtendedFocus to True. | ||
*Switch to Object Inspector's Events tab. Scroll to OnCreateEditor, double click and paste: | *Switch to Object Inspector's Events tab. Scroll to OnCreateEditor, double click and paste: | ||
− | <delphi>procedure TForm1.VSTCreateEditor(Sender: TBaseVirtualTree; | + | <delphi> procedure TForm1.VSTCreateEditor(Sender: TBaseVirtualTree; |
Node: PVirtualNode; Column: TColumnIndex; out EditLink: IVTEditLink); | Node: PVirtualNode; Column: TColumnIndex; out EditLink: IVTEditLink); | ||
− | begin | + | begin |
EditLink:=TStringEditLink.Create; | EditLink:=TStringEditLink.Create; | ||
− | end;</delphi> | + | end;</delphi> |
*On Object Inspector's Events tab. Scroll to OnNewText, double click and paste: | *On Object Inspector's Events tab. Scroll to OnNewText, double click and paste: | ||
− | <delphi>procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode; | + | <delphi> procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode; |
Column: TColumnIndex; NewText: WideString); | Column: TColumnIndex; NewText: WideString); | ||
− | Var | + | Var |
Data: PTreeData; | Data: PTreeData; | ||
− | begin | + | begin |
Data := VST.GetNodeData(Node); | Data := VST.GetNodeData(Node); | ||
Case Column of | Case Column of | ||
Line 742: | Line 734: | ||
2: Data^.Column2:= NewText; | 2: Data^.Column2:= NewText; | ||
End; | End; | ||
− | end;</delphi> | + | end;</delphi> |
Run program, select a node and press F2 to get combobox. On pressing Enter new value should appear on the node. | Run program, select a node and press F2 to get combobox. On pressing Enter new value should appear on the node. | ||
Line 750: | Line 742: | ||
under Uses clause and select Find Declaration. This opens the file on next tab. Go to that file's tab.). Get to the "function TStringEditLink.BeginEdit: Boolean; stdcall;". | under Uses clause and select Find Declaration. This opens the file on next tab. Go to that file's tab.). Get to the "function TStringEditLink.BeginEdit: Boolean; stdcall;". | ||
It looks like: | It looks like: | ||
− | <delphi>function TStringEditLink.BeginEdit: Boolean; stdcall; | + | <delphi> function TStringEditLink.BeginEdit: Boolean; stdcall; |
− | // Notifies the edit link that editing can start now. Descentants may cancel node edit | + | // Notifies the edit link that editing can start now. Descentants may cancel node edit |
− | // by returning False. | + | // by returning False. |
− | begin | + | begin |
Result := not FStopping; | Result := not FStopping; | ||
if Result then | if Result then | ||
Line 763: | Line 755: | ||
FEdit.SetFocus; | FEdit.SetFocus; | ||
end; | end; | ||
− | end;</delphi> | + | end;</delphi> |
Now add "FEdit.Height:=18;". It should look like: | Now add "FEdit.Height:=18;". It should look like: | ||
− | <delphi>function TStringEditLink.BeginEdit: Boolean; stdcall; | + | <delphi> function TStringEditLink.BeginEdit: Boolean; stdcall; |
− | // Notifies the edit link that editing can start now. Descentants may cancel node edit | + | // Notifies the edit link that editing can start now. Descentants may cancel node edit |
− | // by returning False. | + | // by returning False. |
− | begin | + | begin |
Result := not FStopping; | Result := not FStopping; | ||
if Result then | if Result then | ||
Line 781: | Line 773: | ||
FEdit.Height:=18; // <--- Added this line. | FEdit.Height:=18; // <--- Added this line. | ||
end; | end; | ||
− | end;</delphi> | + | end;</delphi> |
Save the file (press Ctrl + S). If you are on the example project, close this (Project -> Close Project). Click on Tools -> Configure "Build Lazarus" ... Select Clean Up + Build All and then click on the Build button. After compile Lazarus should be restarted. Now open the example project and try to edit node on VST. This time it should be ok. | Save the file (press Ctrl + S). If you are on the example project, close this (Project -> Close Project). Click on Tools -> Configure "Build Lazarus" ... Select Clean Up + Build All and then click on the Build button. After compile Lazarus should be restarted. Now open the example project and try to edit node on VST. This time it should be ok. |
Revision as of 00:07, 23 November 2011
│
English (en) │
español (es) │
français (fr) │
polski (pl) │
русский (ru) │
Aqui hay algunos ejemplos acerca de como usar el control VirtualTreeview para Lazarus (probado en win32). La mayoría de estos ejemplos han sido recolectados de la web, escritos para delphi, y de los documentos o tutoriales por Philipp Frenzel y Mike Lischke. Los documentos o tutoriales pueden ser descargados desde http://www.soft-gems.net . Abajo, usted puede encontrar alguna forma rapida de como utilizar VirtualTreeview en Lazarus, no explicaciones detalladas. Para más explicaciones y otros métodos o funciones, obtenga los documentos oficiales y el tutorial.
Ejemplo Tree Listview basico con 3 columnas
1. Instalar el componente. Ejecutar Lazarus.
2. Arrastre un componente TVirtualStringTree (bajo la pagina Controles Visuales).
3. Vaya al editor de código (oprima la tecla F12). Bajo la sentencia Uses agregue una unidad - escriba VirtualTrees (si no existe previamente, no confunda con la unidad VirtualStringTree). Se vera de forma igual o similar a : <delphi> uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, VirtualStringTree, VirtualTrees;</delphi>
4. Vaya al Diseñador de Formularios (oprima la tecla F12). Seleccione el componente Virtual Tree. En el Inspector de Objetos haga clic en Nombre, escriba VST y oprima la tecla Enter (Return). Haga clic en Encabezado (expandalo) -> Columnas, haga clic en el pequeño botón, al lado de "0 elementos". Haga clic 3 veces en el botón agregar para agregar 3 columnas. No cierre esta ventana.
5. En la ventana para Edición de Columna, aparecerá la 3ra. columna como seleccionada. Vaya al Inspector de Objetos. Haga clic en Opciones (expandalo) -> y asigne coAllowClick como False.
6. Haga clic en Texto. Escriba Column2.
7. Haga clic en ancho, escriba 100 y oprima la tecla Enter (Return).
8. Vaya a la ventana para Edición de Columna, seleccione las columnas 1ra. y 2da., y asigne su propiedad como la de arriba (para el campo Texto, use nombres diferentes, ejemplo: Columna0, Columna1).
9. Cierre la ventana para Edición de Columna. Seleccione el componente Virtual Tree en el formulario. En el Inspector de Objetos vaya a Encabezado -> Opciones (expandalo). Asigne coAllowClick como True.
10. Desplacese hacia abajo hasta Style, y asignelo como hsFlatButtons.
11. Desplacese hacia abajo hasta TreeOptions (expandalo) -> MiscOption (expandalo), y asigne toEditable como True. Asigne toGridExtensions como True.
12. Desplacese hacia abajo hasta SelectionOptions (expandalo) -> y asigne toExtendedFocus como True. Asigne toMultiSelect como True. En el Diseñador de Formularios cambie el tamaño del VST (componente Virtual) para para poder visualizar todas las columnas, en caso de que sea necesario.
13. Ahora, para agregar 3 botones en la forma. Arrastrelos desde la paleta de componentes - Pagina Estándar (Etiquetados como "OK").
14. Haga clic en Button1, en el Inspector de Objetos cambie Titulo a "AddRoot". Haga clic en el Button2, cambie el titulo a "AddChild". Cambie el titulo de Button3 a "Delete".
15. Mantenga esto aquí y vaya al editor de código (oprima la tecla F12). En el Editor de Código reemplace la linea:
<delphi> {$mode objfpc}{$H+} with {$MODE DELPHI}</delphi>
16. Bajo la sentencia "implementation" pegue las siguientes lineas de código:
<delphi> type
PTreeData = ^TTreeData; TTreeData = record Column0: String; Column1: String; Column2: String; end;</delphi>
17. Vaya al Diseñador de Formas (oprima la tecla F12). Seleccione el control VST. Vaya al Inspector de Objetos, seleccione la pagina Eventos, desplazese hasta el evento onChange. Haga doble clic en el control combobox.
18. Desplazese hasta el evento onFocusChanged. Haga doble clic y pegue el código siguiente: <delphi> procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex); begin VST.Refresh; end;</delphi>
19. Desplacese hasta el evento onFreeNode. Haga doble clic y pegue el código siguiente: <delphi> procedure TForm1.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var Data: PTreeData; begin Data:=VST.GetNodeData(Node); if Assigned(Data) then begin Data^.Column0 := ; Data^.Column1 := ; Data^.Column2 := ; end; end;</delphi>
20. Desplacese hasta el evento onGetNodeDataSize. Haga doble clic y pegue el código siguiente: <delphi> procedure TForm1.VSTGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
begin NodeDataSize := SizeOf(TTreeData); end;</delphi>
21. Desplacese hasta el evento onGetText. Haga doble clic y pegue el código siguiente: <delphi> procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
Data: PTreeData;
begin
Data := VST.GetNodeData(Node); case Column of 0: CellText := Data^.Column0; 1: CellText := Data^.Column1; 2: CellText := Data^.Column2; end;
end;</delphi>
22. Oprima la tecla F12 para ir al Diseñador de Formas. Haga doble clic en el botón "AddRoot". Haga doble clic y pegue el código siguiente:
<delphi> procedure TForm1.Button1Click(Sender: TObject);
Var Data: PTreeData; XNode: PVirtualNode; Rand: Integer; Begin Randomize; Rand := Random(99); XNode:=VST.AddChild(nil); if VST.AbsoluteIndex(XNode) > -1 then Begin Data := VST.GetNodeData(Xnode); Data^.Column0:= 'One ' + IntToStr(Rand); Data^.Column1:= 'Two ' + IntToStr(Rand + 10); Data^.Column2:= 'Three ' + IntToStr(Rand - 10); End; End;</delphi>
23. Oprima la tecla F9 para Ejecutar el proyecto y revisarlo. Haga clic en el botón "AddRoot" para agregar un nodo. Si no hay problema alguno, el nodo sera agregado al control V.S.T.
24. Detenga la ejecución del programa. En el Diseñador de Formularios haga doble clic en el botón titulado "AddChild". Haga doble clic y pegue el código siguiente:
<delphi> procedure TForm1.Button2Click(Sender: TObject);
var XNode: PVirtualNode; Data: PTreeData; begin if not Assigned(VST.FocusedNode) then Exit; XNode := VST.AddChild(VST.FocusedNode); Data := VST.GetNodeData(Xnode); Data^.Column0:= 'Ch 1'; Data^.Column1:= 'Ch 2'; Data^.Column2:= 'Ch 3';
VST.Expanded[VST.FocusedNode]:=True; end;</delphi>
25. En el Diseñador de Formularios haga doble clic en el botón titulado "Delete". Haga doble clic y pegue el código siguiente:
<delphi> procedure TForm1.Button3Click(Sender: TObject);
begin VST.DeleteSelectedNodes; end;</delphi>
26. Ejecute el proyecto, oprimiendo la tecla F9 para revisarlo. Haga varias pruebas, agregando algunos nodos principales, nodos hijos y eliminelos.
27. Intente editar un nodo. Seleccione un nodo y oprima la tecla F2, y escriba un nuevo valor. Si puede ver lo que esta escribiendo, entonces, el paso esta bien. De lo contrario, lea la sección siguiente titulada "Cuando la edición de celda no puede verse".
28. Para obtener que el V.S.T. muestre el nuevo valor capturado después de la edición, vaya al Diseñador de Formas, y seleccione V.S.T. Haga doble clic, en el combo del Inspector de Objetos -> Events -> OnNewText. Haga doble clic y pegue el código siguiente:
<delphi> procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; NewText: WideString); Var Data: PTreeData; begin Data := VST.GetNodeData(Node); Case Column of 0: Data^.Column0:= NewText; 1: Data^.Column1:= NewText; 2: Data^.Column2:= NewText; End; end;</delphi>
Hasta ahora, el ejemplo para uso básico, termina aquí. Usted podría arrastrar algunos botones adicionales en la forma para probar algunos de los comandos mencionados, mas adelante. El paso siguiente, podría ser, desplegar una casilla para marcar o checkbox, imagen, color para tipo de fuente de texto, o agregar un combo al nodo.
- Otra forma para agregar el nodo raíz:
<delphi> procedure TForm1.Button8Click(Sender: TObject);
begin with VST do RootNodeCount:=RootNodeCount+1; end;</delphi>
- Otra forma para agregar un nodo hijo:
<delphi> procedure TForm1.Button9Click(Sender: TObject);
begin if Assigned(VST.FocusedNode) Then VST.ChildCount[VST.FocusedNode]:=VST.ChildCount[VST.FocusedNode]+1; end;</delphi>
- Determinar y eliminar los nodos hijos de un nodo:
<delphi> procedure TForm1.Button4Click(Sender: TObject);
Var c: Integer; begin if not Assigned(VST.FocusedNode) then Exit; If VST.HasChildren[VST.FocusedNode] then Begin c := VST.ChildCount[VST.FocusedNode]; VST.DeleteChildren(VST.FocusedNode); ShowMessage('Number of deleted child:' + #13#10 + IntToStr(c)); End; end;</delphi>
- Eliminar un nodo:
<delphi> procedure TForm1.Button5Click(Sender: TObject);
begin {VST.Clear; //Delete All Nodes} if not Assigned(VST.FocusedNode) then Exit; VST.DeleteNode(VST.FocusedNode); end;</delphi>
- Buscar y seleccionar un nodo:
<delphi> procedure TForm1.Button6Click(Sender: TObject);
var XNode: PVirtualNode; Data: PTreeData; begin XNode:= VST.GetFirst;
while XNode <> nil do begin Data:=VST.GetNodeData(XNode); if Data^.Column0 = '1' then begin VST.ClearSelection; VST.Selected[XNode]:=True; VST.SetFocus; break; end else XNode:= VST.GetNextSibling(XNode); end; end;</delphi>
- Determinar el nodo padre de un nodo:
<delphi> procedure TForm1.Button13Click(Sender: TObject);
var XNode: PVirtualNode; begin if not Assigned(VST.FocusedNode) then Exit; XNode:=VST.FocusedNode; while VST.GetNodeLevel(XNode) > 0 do Begin XNode := XNode.Parent; VST.Selected[XNode]:= True; End; VST.Refresh; VST.SetFocus; end;</delphi>
- Buscar todos los nodos:
<delphi> procedure TForm1.Button7Click(Sender: TObject);
Var XNode: PVirtualNode; Data: PTreeData; begin If VST.GetFirst = nil then Exit; XNode:=nil; Repeat if XNode = nil then XNode:=VST.GetFirst Else XNode:=VST.GetNext(XNode); Data:=VST.GetNodeData(XNode); If (Data^.Column0 = '1') OR (Data^.Column1 = '1') OR (Data^.Column2 = '1') then Begin ShowMessage('Found at Node Level : ' + IntToStr(VST.GetNodeLevel(XNode)) ); break; End; Until XNode = VST.GetLast(); end;</delphi>
- Buscar el nodo siguiente:
<delphi> procedure TForm1.Button8Click(Sender: TObject);
var XNode: PVirtualNode; Data: PTreeData; begin if not Assigned(VST.GetFirst) then Exit else XNode := VST.GetFirst; repeat XNode := VST.GetNext(XNode); Data := VST.GetNodeData(XNode); if Pos(LowerCase(SearchEdit.Text), LowerCase(Data^.Column0)) > 0 then begin VST.FocusedNode := XNode; VST.Selected[XNode] := True; if MessageDlg('Item found?', mtConfirmation, mbYesNo, 0) = mrYes then begin VST.Expanded[XNode] := True; VST.Refresh; VST.SetFocus; Break; end; end; until XNode = VST.GetLast; end;</delphi>
- Insertar Nodo:
<delphi> procedure TForm1.Button12Click(Sender: TObject);
var XNode: PVirtualNode; begin If Assigned(VST.FocusedNode) then begin XNode := VST.InsertNode(VST.FocusedNode,amInsertBefore); // To Insert After Selected Node. {XNode := VST.InsertNode(VST.FocusedNode,amInsertAfter);} VST.Refresh; end; end;</delphi>
- Asignar la altura de un nodo:
<delphi> procedure TForm1.Button14Click(Sender: TObject);
begin If Assigned(VST.FocusedNode) then VST.NodeHeight[VST.FocusedNode] := 32; end;</delphi>
- Guardar y Cargar:
El arbol simple (sin columnas), puede ser guardado y recargado con:
<delphi> VST.SaveToFile('filename.dat');
VST.LoadFromFile('filename.dat');</delphi>
Para guardar y cargar el ejemplo mencionado arriba, coloque 2 botones en la forma, cambie el titulo de un boton a "Guardar", y el titulo del otro boton a "Cargar". Seleccione el V.S.T., En el Inspector de Objetos -> TreeOptions -> StringOptions. Asegurese, que el valor de la propiedad toSaveCaptions este asignada como True. Vaya a la pagina del Inspector de Eventos Events. Desplazece hasta OnLoadNode, haga doble cilc y pegue el codigo siguiente:
<delphi> procedure TForm1.VSTLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
Stream: TStream); Var Data: PTreeData; Len: Integer; begin Data := VST.GetNodeData(Node); Stream.read(Len, SizeOf(Len)); SetLength(Data^.Column0, Len); Stream.read(PChar(Data^.Column0)^, Len);
Stream.read(Len, SizeOf(Len)); SetLength(Data^.Column1, Len); Stream.read(PChar(Data^.Column1)^, Len);
Stream.read(Len, SizeOf(Len)); SetLength(Data^.Column2, Len); Stream.read(PChar(Data^.Column2)^, Len); end;</delphi>
Otra vez, en la pagina Events del Inspector de Objetos, desplazece hasta OnSaveNode, haga doble cilc y pegue el codigo siguiente:
<delphi> procedure TForm1.VSTSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
Stream: TStream); Var Data: PTreeData; Len: Integer; begin Data := VST.GetNodeData(Node); Len := Length(Data^.Column0); Stream.write(Len, SizeOf(Len)); Stream.write(PChar(Data^.Column0)^, Len);
Len := Length(Data^.Column1); Stream.write(Len, SizeOf(Len)); Stream.write(PChar(Data^.Column1)^, Len);
Len := Length(Data^.Column2); Stream.write(Len, SizeOf(Len)); Stream.write(PChar(Data^.Column2)^, Len); end;</delphi>
En el Diseñador de Formularios, haga doble clic en el boton titulado "Save" o "Guargar", y pegue el codigo siguiente:
<delphi> procedure TForm1.Button10Click(Sender: TObject);
begin VST.SaveToFile('C:\vst.dat'); end;</delphi>
En el Diseñador de Formularios, haga doble clic en el boton titulado "Load" o "Cargar", y pegue el codigo siguiente:
<delphi> procedure TForm1.Button11Click(Sender: TObject); begin
VST.LoadFromFile('C:\vst.dat');
end; </delphi>
Ahora, haga pruebas, para guardar y volver a cargar el arbol.
- Problema de desplazamiento
El encabezado de control vistaarbol desaparece parcialmente o completamente al desplazarse. No pude encontrar una buena solucion a esto. Una forma de sobrepasar esto, es asignar la altura del encabezado a 0, y utilizar una etiqueta generica para las columnas, y todas las columnas estan visibles sin desplazamiento horizontal. O, la altura del encabezado puede ser asignada un valor mas alto, entre 25 o 30. El metodo VST.Refresh puede ser asignado al evento OnScroll.
- Cambiar el tamaño de las columnas
No fue posible cambiar el tamaño de las columnas, arrastrando el raton en el encabezado del V.S.T. Tal vez, sea debido al "bug" del encabezado, o tal vez, omiti algo. En caso de que la causa haya sido el encabezado, tal vez sea corregido en la siguiente version de Lazarus. Puede ver este enlace: http://bugs.freepascal.org/view.php?id=11209
De cualquier forma, es posible cambiar el tamaño de las columnas por medio de codigo. Cuando presione mantenga presionado el boton derecho del raton, y gire la rueda arriba, el ancho de la columna seleccionada se incrementa, y manteniendo presionado abajo, el boton derecho del raton y girando hacia abjo la rueda del raton, podra decrementar el ancho de la columna seleccionada. Para hacer esto:
1. Agregue una variable en el editor de codigo llamada como CurCol: Integer; Se vera como esto:
<delphi> var
Form1: TForm1; CurCol: Integer; // <- Agregue solo esta linea.
implementation
{ TForm1 }</delphi>
2. En el diseñador de Formas, haga doble clic en la forma para generar un procedimiento para el evento OnCreate. En el procedimiento OnCreate, escriba Form1.OnMouseWheelUp:= y presione Ctrl+Shift+C, esto completara el codigoy hara el esqueleto del procedimiento para el evento MouseWheelUp. ahora, regrese al procedimiento TForm1.FormCreate(Sender: TObject); Y agregue otro procedimiento, esta vez para el evento MouseWheelDown. Escriba Form1.OnMouseWheelDown:= y oprima la combinacion de teclas Ctrl+Shift+C, para generar el procedimiento para el evento MouseWheelDown. El procedimiento FormCreate se mira asi:
<delphi> procedure TForm1.FormCreate(Sender: TObject);
begin Form1.OnMouseWheelUp:=@Form1MouseWheelUp; Form1.OnMouseWheelDown:=@Form1MouseWheelDown; end;</delphi>
3. Capture el procedimiento para el evento TForm1.Form1MouseWheelUp procedure como:
<delphi> procedure TForm1.Form1MouseWheelUp(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean); begin If VST.Focused then if ssRight in Shift then VST.Header.Columns[CurCol].Width:= VST.Header.Columns[CurCol].Width + 10; end;</delphi>
4. Capture el procedimiento para el evento TForm1.Form1MouseWheelDown procedure como:
<delphi> procedure TForm1.Form1MouseWheelDown(Sender: TObject; Shift: TShiftState;
MousePos: TPoint; var Handled: Boolean); begin If VST.Focused then if ssRight in Shift then VST.Header.Columns[CurCol].Width:= VST.Header.Columns[CurCol].Width - 10; end;</delphi>
5. Vaya al Diseñador de Formas (puede oprimir F12), seleccione el V.S.T., En la pagina Events, del Inspector de Objetos, desplazece hasta OnFocusChanged, haga doble clic y pegue el codigo siguiente:
<delphi> procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex); begin CurCol:=Column; end;</delphi>
Cuando ejecute el programa, haga clic en una columna, despues mantenga presionado abajo, el boton derecho del raton, y gire la rueda arriba, para incrementar el ancho. Gire la rueda abajo decrementar los valores mencionados.
Podria modificar los procedimientos anteriores, para ajustar un poco el resultado, si es necesario. O, agregar algun evento para el teclado, con algo como "if (key=187) and (ssShift in Shift) then" para utilizar la combinacion de teclas Shift + "+".
Checkbox
En el Diseñador de Formas seleccione el control V.S.T. Vaya:
- Object Inspector -> Properties -> CheckImageKind y seleccione ckDarkCheck.
- Object Inspector -> Properties -> TreeOptions -> MiscOptions -> toCheckSupport y asignelo como True.
Ahora, cambie a la pagina de Events.
- Scroll to OnInitNode. Double click and paste the followings:
<delphi> procedure TForm1.VSTInitNode(Sender: TBaseVirtualTree; ParentNode,
Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates); Var Level: Integer; begin Level := VST.GetNodeLevel(Node); if Level = 0 then Node.CheckType:=ctCheckBox;
if Level = 2 then Node.CheckType:=ctRadioButton;
if Level = 1 then begin Node.CheckType:=ctTriStateCheckBox; Node.CheckState := csCheckedNormal; end;
if Level = 3 then Node.CheckType:=ctButton; end;</delphi>
Run the program, add rootnode and child then child of the child, and check if you can check and uncheck properly. If not, close the program. Go to the Object Inspector's Events tab.
- Scroll to OnChecked, double click and paste:
<delphi> procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode);
begin vst.Refresh; end;</delphi>
- Scroll to OnChecking, double click and paste:
<delphi> procedure TForm1.VSTChecking(Sender: TBaseVirtualTree; Node: PVirtualNode;
var NewState: TCheckState; var Allowed: Boolean); begin VST.Refresh; end;</delphi>
Hope now it is ok. To determine checkbox state use like:
<delphi> If XNode.CheckState = csCheckedNormal then ShowMessage('Checked.');</delphi>
Other states are:
<delphi> csUncheckedNormal = unchecked and not pressed
csUncheckedPressed = unchecked and pressed csCheckedNormal = checked and not pressed csCheckedPressed = checked and pressed csMixedNormal = 3-state check box and not pressed csMixedPressed = 3-state check box and pressed</delphi>
Other types are:
<delphi>ctNone
ctTriStateCheckBox
ctCheckBox
ctRadioButton
ctButton</delphi>
- To Catch Checkbox's Button (ctButton) Click
Go to Object Inspector's Events tab. Scroll to OnChecked, double click and paste: <delphi>procedure TForm1.VSTChecked(Sender: TBaseVirtualTree; Node: PVirtualNode); begin
if Node.CheckType = ctButton then ShowMessage('Ok.'); VST.Refresh;
end;</delphi>
End of checkbox.
Images
To show image on VST nodes, a list of image should be created.
- Go to the Component Palette -> Common Controls. Select and drop a TImageList component on the form. Right click on the component icon and select ImageList Editor. Click on Add button and and select some images (at least 3 for now), then click on tick button to accept and close the ImageList Editor. By the way, there are some nice images you can download from http://www.famfamfam.com/lab/icons/silk/
- Now on the Form Designer select VST, and on Object Inspector's Properties tab, scroll to Images and select ImageList1
- On Object Inspector's Events tab scroll to OnGetImageIndex, double click and paste:
<delphi>procedure TForm1.VSTGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer);
begin
if Kind in [ikNormal , ikSelected] then // Either Selected or not begin if Column = 0 then // if 1st Column ImageIndex:=0; // 1st Image of the ImageList1
if Column = 1 then // if 2nd Column ImageIndex:=1; // 2nd Image of the ImageList1
if Sender.FocusedNode = Node then // Only show if Focused if Column =2 then // if 3rd Column ImageIndex:=2; // 3rd Image of the ImageList1 end; {Sender.NodeHeight[node]:=40; //If Image is big}
end;</delphi>
Font Colour
On the Form Designer select VST, and on Object Inspector's Events tab, scroll to OnPaintText, double click and paste: <delphi>procedure TForm1.VSTPaintText(Sender: TBaseVirtualTree;
const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType);
Var
Data: PTreeData;
begin
Data := VST.GetNodeData(Node); if Data^.Column0 = 'sky' then TargetCanvas.Font.Color:=clBlue; if Column = 1 then begin TargetCanvas.Font.Color:=clRed; TargetCanvas.Font.Style:= Font.Style + [fsItalic]; end; if Column = 2 then begin
// ImageList1.Draw(Form1.Canvas,-1,-1,2); {draw top left of form, 3rd image of ImageList1??}
TargetCanvas.Font.Size:= 9; TargetCanvas.Font.Color:=clHighlightText; end;
end;</delphi>
Adding A Combobox
- I guess you have an open project on Lazarus IDE having VST on it and can edit the nodes. If not see the "Basic Tree Listview With 3 Columns" above, and atleast complete steps 1 to 21.
- Bellow there is an unit file named combo. Copy that unit and save as combo.pas inside the project directory. Under your program's uses clause add combo. So it may look like:
<delphi> uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, VirtualStringTree, VirtualTrees, combo;</delphi>
- The combo.pas unit
<delphi> unit combo;
{$mode delphi}
interface
uses Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, VirtualStringTree, VirtualTrees, messages, windows, StdCtrls;
type TStringEditLink = class(TInterfacedObject, IVTEditLink) private FEdit: TWinControl; FTree: TVirtualStringTree; FNode: PVirtualNode; FColumn: Integer; protected procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); public destructor Destroy; override; function BeginEdit: Boolean; stdcall; function CancelEdit: Boolean; stdcall; function EndEdit: Boolean; stdcall; function GetBounds: TRect; stdcall; function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall; procedure ProcessMessage(var Message: TMessage); stdcall; procedure SetBounds(R: TRect); stdcall; end;
implementation
destructor TStringEditLink.Destroy; begin FEdit.Free; inherited; end;
procedure TStringEditLink.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin case Key of VK_ESCAPE: begin FTree.CancelEditNode; Key := 0; FTree.setfocus; end; VK_RETURN: begin PostMessage(FTree.Handle, WM_KEYDOWN, VK_DOWN, 0); Key := 0; FTree.EndEditNode; FTree.setfocus; end; End; //case end;
function TStringEditLink.BeginEdit: Boolean; begin Result := True; //FEdit.Height:=(FTree.DefaultNodeHeight - 1); //Needed for editbox. Not combo FEdit.Show; TComboBox(FEdit).DroppedDown:=True; FEdit.SetFocus; end;
function TStringEditLink.CancelEdit: Boolean; begin Result := True; FEdit.Hide; end;
function TStringEditLink.EndEdit: Boolean; var S: WideString; begin Result := True; S:= TComboBox(FEdit).Text; FTree.Text[FNode, FColumn] := S;
FTree.InvalidateNode(FNode); FEdit.Hide; FTree.SetFocus; end;
function TStringEditLink.GetBounds: TRect; begin Result := FEdit.BoundsRect; end;
function TStringEditLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; begin Result := True; FTree := Tree as TVirtualStringTree; FNode := Node; FColumn := Column;
FEdit.Free; FEdit := nil;
FEdit := TComboBox.Create(nil); with FEdit as TComboBox do begin Visible := False; Parent := Tree; Items.Add('Google'); Items.Add('Yahoo'); Items.Add('Altavista'); OnKeyDown := EditKeyDown; end; end;
procedure TStringEditLink.ProcessMessage(var Message: TMessage); begin FEdit.WindowProc(Message); end;
procedure TStringEditLink.SetBounds(R: TRect); var Dummy: Integer; begin FTree.Header.Columns.GetColumnBounds(FColumn, Dummy, R.Right); FEdit.BoundsRect := R; end;
End.</delphi>
- After saving the file, on the Form Designer select VST and on Object Inspector's Properties, scroll to TreeOptions -> MiscOptions, set toEditable to True. Then get to TreeOptions -> SelectionOptions, set toExtendedFocus to True.
- Switch to Object Inspector's Events tab. Scroll to OnCreateEditor, double click and paste:
<delphi> procedure TForm1.VSTCreateEditor(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; out EditLink: IVTEditLink); begin EditLink:=TStringEditLink.Create; end;</delphi>
- On Object Inspector's Events tab. Scroll to OnNewText, double click and paste:
<delphi> procedure TForm1.VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; NewText: WideString); Var Data: PTreeData; begin Data := VST.GetNodeData(Node); Case Column of 0: Data^.Column0:= NewText; 1: Data^.Column1:= NewText; 2: Data^.Column2:= NewText; End; end;</delphi>
Run program, select a node and press F2 to get combobox. On pressing Enter new value should appear on the node.
If Cell Editing Can't Be Seen
Open VirtualStringTree.pas unit file (if you are still on the above example project, right click on VirtualStringTree under Uses clause and select Find Declaration. This opens the file on next tab. Go to that file's tab.). Get to the "function TStringEditLink.BeginEdit: Boolean; stdcall;". It looks like: <delphi> function TStringEditLink.BeginEdit: Boolean; stdcall;
// Notifies the edit link that editing can start now. Descentants may cancel node edit // by returning False.
begin Result := not FStopping; if Result then begin FEdit.Show; FEdit.SelectAll; FEdit.SetFocus; end; end;</delphi>
Now add "FEdit.Height:=18;". It should look like:
<delphi> function TStringEditLink.BeginEdit: Boolean; stdcall;
// Notifies the edit link that editing can start now. Descentants may cancel node edit // by returning False.
begin Result := not FStopping; if Result then begin FEdit.Show; FEdit.SelectAll; FEdit.SetFocus; FEdit.Height:=18; // <--- Added this line. end; end;</delphi>
Save the file (press Ctrl + S). If you are on the example project, close this (Project -> Close Project). Click on Tools -> Configure "Build Lazarus" ... Select Clean Up + Build All and then click on the Build button. After compile Lazarus should be restarted. Now open the example project and try to edit node on VST. This time it should be ok.
External links
- Programando en Pascal - Spanish tutorial focused on FPC/Lazarus, hosted in Wikibooks.
(In progress)
[En desarrollo]