Difference between revisions of "TTreeView/es"

From Lazarus wiki
Jump to navigationJump to search
m (Fixed syntax highlighting)
 
(29 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 +
{{TTreeView}}
 +
 
==Añadir un nuevo elemento mediante código==
 
==Añadir un nuevo elemento mediante código==
  
Line 5: Line 7:
 
==Crear un TreeView que carga elementos solamente cuando se expande==
 
==Crear un TreeView que carga elementos solamente cuando se expande==
  
To add the expansion symbol to a node without subitems use:
+
Para añadir el símbolo de expansión a un nodo que no contiene subelementos escribimos la siguiente sentencia:
  
<syntaxhighlight>MyNode.HasChildren := True;</syntaxhighlight>
+
<syntaxhighlight lang=pascal>MiNodo.HasChildren := True;</syntaxhighlight>
  
And then set an event handler for the OnExpanding event. In this even you should return if the expansion can actually be made or not and when yes, you should add subitems to the node. If the expansion cannot be done, the expansion symbol will be automatically removed even if you have previously set HasChildren to true.
+
Y establecemos un manejador de eventos para el evento OnExpanding. En este evento se debería retornar si se puede o no realizar la expansión y caso de que sea afirmativo se añadirían subelementos al nodo. Si la expansión no puede realizarse entonces desaparece automáticamente el símbolo de expansión incluso si previamente se ha establecido el valor de HasChildren a true.
  
 
==Un pequeño ejemplo de uso de TTreeview==
 
==Un pequeño ejemplo de uso de TTreeview==
  
Here is a quick & dirty example - testeado en Lazarus 0.9.26 bajo Windows:
+
Aquí tenéis un ejemplo rápido e informal - testeado en Lazarus 0.9.26 bajo Windows:
  
 
Crear una nueva aplicación.  En Form1 añadir un treeview vacío, un button1 con caption "Añadir hijo" y un button2 con caption "Borrar"
 
Crear una nueva aplicación.  En Form1 añadir un treeview vacío, un button1 con caption "Añadir hijo" y un button2 con caption "Borrar"
Line 19: Line 21:
 
Para los buttons' con su evento OnClick, asignar el siguiente código, compilar y ejecutar.
 
Para los buttons' con su evento OnClick, asignar el siguiente código, compilar y ejecutar.
  
Codigo:
+
Código:
 +
 
 +
<syntaxhighlight lang=pascal>
  
<syntaxhighlight>procedure TForm1.Button1Click(Sender: TObject);
+
procedure TForm1.Button1Click(Sender: TObject);
 
var  
 
var  
 
   i: integer;
 
   i: integer;
Line 34: Line 38:
 
   
 
   
 
   // Establer un texto simple para cada nuevo nodo: Nodo1 , Nodo2, etc
 
   // Establer un texto simple para cada nuevo nodo: Nodo1 , Nodo2, etc
   i := treeview1.Items.Count; { nos retorna la cuenta total de elementos }
+
   i := treeview1.Items.Count; // Nos retorna la cuenta total de elementos.
   s := 'Nodo ' + inttostr(i); { crea la cadena de texto 'Node ' más el número resultante de conversión de entero su }
+
   s := 'Nodo ' + inttostr(i); // Crea la cadena de texto 'Node ' más el número resultante de conversión de entero su  
   { equivalente en texto }
+
   // equivalente en texto.
 
   // Añade un nuevo nodo al nodo actualmente seleccionado.
 
   // Añade un nuevo nodo al nodo actualmente seleccionado.
   if TreeView1.Selected <> nil then { Si tenemos seleccionado un nodo entonces hacer lo siguiente }
+
   if TreeView1.Selected <> nil then // Si tenemos seleccionado un nodo entonces hacer lo siguiente.
     Treeview1.Items.AddChild(Treeview1.Selected ,s); { Añadir un elemento como hijo al actualmente seleccionado }
+
     Treeview1.Items.AddChild(Treeview1.Selected ,s); // Añadir un elemento como hijo al actualmente seleccionado.
 
end;
 
end;
 
   
 
   
 
procedure TForm1.Button2Click(Sender: TObject);
 
procedure TForm1.Button2Click(Sender: TObject);
 
   
 
   
   // Un procedimiento para borrar nodos recursivmente
+
   // Un procedimiento para borrar nodos recursivamente.
   Procedure DeleteNode(Node:TTreeNode);
+
   Procedure DeleteNode(Nodo:TTreeNode);
 
   begin
 
   begin
     while Node.HasChildren do DeleteNode(node.GetLastChild); { mientras el nodo tenga hijos realizar borrado último nodo hijo }
+
     while Nodo.HasChildren do DeleteNode(Nodo.GetLastChild); { mientras el nodo tenga hijos realizar borrado último nodo hijo }
     TreeView1.Items.Delete(Node) ; { borra nodo que ya no contiene nodos hijo }  
+
     TreeView1.Items.Delete(Nodo) ; { borra nodo que ya no contiene nodos hijo }  
 
   end;
 
   end;
 
   
 
   
 
begin
 
begin
   if TreeView1.Selected = nil then exit; { salir del borrado caso de que no tengamos seleccionado un nodo }
+
   if TreeView1.Selected = nil then exit; // salir del borrado caso de que no tengamos seleccionado un nodo }
 
   // Si el nodo seleccionado tiene nodos hijo, primero preguntar por confirmación
 
   // Si el nodo seleccionado tiene nodos hijo, primero preguntar por confirmación
 
   If treeview1.Selected.HasChildren then
 
   If treeview1.Selected.HasChildren then
     if messagedlg('¿Borrar nodo y todos los nodos hijo?',mtConfirmation,
+
     if messagedlg('¿Borrar nodo seleccionado y todos sus nodos hijo?',mtConfirmation,
                 [mbYes,mbNo],0) <> mrYes then exit; { Muestra mensaje de confirmación de borrado (pulsadores Si/No), caso de que }
+
                 [mbYes,mbNo],0) <> mrYes then exit; // Muestra mensaje de confirmación de borrado (pulsadores Si/No), caso de que  
                                                     { la contestación sea diferente de Si, entonces sale del if sin borrar nodo }
+
                                                     // la contestación sea diferente de Si, entonces sale del if sin borrar nodo.
   DeleteNode(TreeView1.Selected); { Borra el nodo actualmente seleccionado }
+
   DeleteNode(TreeView1.Selected); // Borra el nodo actualmente seleccionado.
end;</syntaxhighlight>
+
end;
 +
</syntaxhighlight>
  
 
Cuando se ejecuta, el treeview está vacío,. Si se hace click en "Añadir hijo", se crea un nodo raíz. Después de esto se crea un nodo hijo en el nodo que tengamos seleccionado haciendo click en el pulsador "Añadir hijo".
 
Cuando se ejecuta, el treeview está vacío,. Si se hace click en "Añadir hijo", se crea un nodo raíz. Después de esto se crea un nodo hijo en el nodo que tengamos seleccionado haciendo click en el pulsador "Añadir hijo".
Line 65: Line 70:
 
El pulsador Borrar lo que hace es borrar el nodo actualmente seleccionado. Si no tiene nodos hijo lo borrara inmediatamente, pero si los tiene preguntará primero para confirmar su borrado.
 
El pulsador Borrar lo que hace es borrar el nodo actualmente seleccionado. Si no tiene nodos hijo lo borrara inmediatamente, pero si los tiene preguntará primero para confirmar su borrado.
  
== Freeing TreeNode Data ==
+
==Liberando los datos del TreeNode==
  
Utilizar el evento OnDeletion de Treeview para liberar el objeto creado.
+
Utilizar el evento OnDeletion de Treeview para liberar el objeto creado:
 +
 
 +
<syntaxhighlight lang=pascal>
  
<syntaxhighlight>
 
 
procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
 
procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
 
begin
 
begin
   TMyObject(Node.Data).Free; { Libera los recursos asignados al objeto (así dejamos memoria libre para otros objetos) }
+
   TMyObject(Node.Data).Free; // Libera los recursos asignados al objeto (así dejamos memoria libre para otros objetos).
 
end;
 
end;
 +
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 82: Line 89:
 
# Establecer la propiedad "Drag Mode" de treeview al valor DmAutomatic.
 
# Establecer la propiedad "Drag Mode" de treeview al valor DmAutomatic.
 
# Crear un evento del tipo "OndragOver" (solapa de eventos en el inspector de objetos):  
 
# Crear un evento del tipo "OndragOver" (solapa de eventos en el inspector de objetos):  
<syntaxhighlight>procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;  State: TDragState; var Accept: Boolean);
+
<syntaxhighlight lang=pascal>procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;  State: TDragState; var Accept: Boolean);
 
begin
 
begin
 
   Accept := true;
 
   Accept := true;
Line 88: Line 95:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Espero que esta información sea de ayuda.
+
Espero que esta información sea de ayuda. Adicionalmente podéis cargar el proyecto de ejemplo que acompaña a Lazarus (tv_add_remove.lpi) o bien ver el tutorial que se encuentra en http://users.iafrica.com/d/da/dart/Delphi/TTreeView/TreeView.html
 +
 
 +
[[Category:Components/es]]
 +
[[Category:Tutorials/es]]
 +
 
 +
== Personalizando un TreeView ==
 +
 
 +
 
 +
Añado esta sección debido a una consulta en el foro sobre como cambiar el color del texto en un TreeView [http://forum.lazarus.freepascal.org/index.php/topic,30095.msg191058/topicseen.html#new].
 +
 
 +
 
 +
 
 +
La respuesta del usuario '''GetMem''' es que se debe establecer el valor '''tvoThemedDraw''' a '''False''', ya que por defecto vale '''True'''.
 +
 
 +
En el Inspector de Objetos para TreeView dentro de las opciones disponibles lo encontramos en:
 +
 
 +
 
 +
[[File:treeviewoptions.png|center|450px]]
 +
 
 +
 
 +
Aquí el resto de valores para las opciones que aparecen son los establecidos por defecto para un TreeView.
 +
 
 +
 
 +
De esta forma nos permite personalizar más el color de la fuente que de otra manera estando '''tvoThemedDraw''' establecido al valor '''true''' utiliza por defecto el color (y la fuente) que tenga el tema visual de escritorio en uso (la otra posibilidad es deshabilitar el tema).
 +
 
 +
Esto se aplica a todos los nodos del TreeView, pero en caso de necesitar aplicar diferentes colores a los nodos el ejemplo que nos pone el usuario '''molly''' es:
 +
 
 +
<syntaxhighlight lang=pascal>
 +
 
 +
    // En tiempo de creación del formulario establecemos tvoThemedDraw a false
 +
    // y llenamos el TreeView con 10 elementos: item 1,item 2,....,item 10 (el índice comienza por 0 para item 1).
 +
 
 +
    procedure TForm1.FormCreate(Sender: TObject); 
 +
 
 +
    var i:integer;
 +
 
 +
    begin
 +
 
 +
      TreeView1.Options := TreeView1.Options - [tvoThemedDraw];
 +
 
 +
      For i := 1 to 10 do TreeView1.Items.Add(nil, 'item ' + IntToStr(i));
 +
 
 +
    end;
 +
 
 +
</syntaxhighlight>   
 +
 
 +
 
 +
Y asignamos al evento '''OnDrawItemEvent''':
 +
 
 +
 
 +
<syntaxhighlight lang=pascal>
 +
 
 +
    // En nuestro TreeView personalizado, chequeamos si su índice de nodo es par o impar.
 +
    // y cambia el color de texto a rojo si es impar (odd) o a verde en caso contrario.
 +
 
 +
    procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;
 +
 
 +
      Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
 +
 
 +
    begin
 +
 
 +
      with Sender as TCustomTreeView do
 +
 
 +
        if odd(Node.Index)
 +
 
 +
        then Canvas.Font.Color:= clRed
 +
 
 +
        else Canvas.Font.Color:= clGreen;
 +
 
 +
    end;
 +
 
 +
</syntaxhighlight>
 +
 
 +
 
 +
Siendo el resultado:
 +
 
  
[[Category:Components]]
+
[[File:customtreeview.png|center|350px]]
[[Category:Tutorials]]
 

Latest revision as of 01:55, 2 March 2020

English (en) español (es) suomi (fi) français (fr) magyar (hu) русский (ru)

Añadir un nuevo elemento mediante código

Se puede añadir un nuevo elemento mediante TTreeView.Items.AddChild o bien AddChildObject.

Crear un TreeView que carga elementos solamente cuando se expande

Para añadir el símbolo de expansión a un nodo que no contiene subelementos escribimos la siguiente sentencia:

MiNodo.HasChildren := True;

Y establecemos un manejador de eventos para el evento OnExpanding. En este evento se debería retornar si se puede o no realizar la expansión y caso de que sea afirmativo se añadirían subelementos al nodo. Si la expansión no puede realizarse entonces desaparece automáticamente el símbolo de expansión incluso si previamente se ha establecido el valor de HasChildren a true.

Un pequeño ejemplo de uso de TTreeview

Aquí tenéis un ejemplo rápido e informal - testeado en Lazarus 0.9.26 bajo Windows:

Crear una nueva aplicación. En Form1 añadir un treeview vacío, un button1 con caption "Añadir hijo" y un button2 con caption "Borrar"

Para los buttons' con su evento OnClick, asignar el siguiente código, compilar y ejecutar.

Código:

procedure TForm1.Button1Click(Sender: TObject);
var 
  i: integer;
  s: string;
begin
  // si no hay nodos, crear un nodo raíz con un padre establecido al valor Nil
  if TreeView1.Items.Count = 0 then
    begin
      Treeview1.Items.Add (nil,'Nodo Raíz');
      exit;
    end;
 
  // Establer un texto simple para cada nuevo nodo: Nodo1 , Nodo2, etc
  i := treeview1.Items.Count; // Nos retorna la cuenta total de elementos. 
  s := 'Nodo ' + inttostr(i); // Crea la cadena de texto 'Node ' más el número resultante de conversión de entero su 
  // equivalente en texto.
  // Añade un nuevo nodo al nodo actualmente seleccionado.
  if TreeView1.Selected <> nil then // Si tenemos seleccionado un nodo entonces hacer lo siguiente.
    Treeview1.Items.AddChild(Treeview1.Selected ,s); // Añadir un elemento como hijo al actualmente seleccionado.
end;
 
procedure TForm1.Button2Click(Sender: TObject);
 
  // Un procedimiento para borrar nodos recursivamente.
  Procedure DeleteNode(Nodo:TTreeNode);
  begin
    while Nodo.HasChildren do DeleteNode(Nodo.GetLastChild); { mientras el nodo tenga hijos realizar borrado último nodo hijo }
    TreeView1.Items.Delete(Nodo) ; { borra nodo que ya no contiene nodos hijo } 
  end;
 
begin
  if TreeView1.Selected = nil then exit; // salir del borrado caso de que no tengamos seleccionado un nodo }
  // Si el nodo seleccionado tiene nodos hijo, primero preguntar por confirmación
  If treeview1.Selected.HasChildren then
    if messagedlg('¿Borrar nodo seleccionado y todos sus nodos hijo?',mtConfirmation,
                 [mbYes,mbNo],0) <> mrYes then exit; // Muestra mensaje de confirmación de borrado (pulsadores Si/No), caso de que 
                                                     // la contestación sea diferente de Si, entonces sale del if sin borrar nodo.
  DeleteNode(TreeView1.Selected); // Borra el nodo actualmente seleccionado.
end;

Cuando se ejecuta, el treeview está vacío,. Si se hace click en "Añadir hijo", se crea un nodo raíz. Después de esto se crea un nodo hijo en el nodo que tengamos seleccionado haciendo click en el pulsador "Añadir hijo".

El pulsador Borrar lo que hace es borrar el nodo actualmente seleccionado. Si no tiene nodos hijo lo borrara inmediatamente, pero si los tiene preguntará primero para confirmar su borrado.

Liberando los datos del TreeNode

Utilizar el evento OnDeletion de Treeview para liberar el objeto creado:

procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
begin
  TMyObject(Node.Data).Free; // Libera los recursos asignados al objeto (así dejamos memoria libre para otros objetos). 
end;

Utilizando Drag y Drop (arrastrar y soltar) en un TreeView

Si se quiere permitir la función de arrastrar y soltar en un treeview se necesita lo siguiente:

  1. Establecer la propiedad "Drag Mode" de treeview al valor DmAutomatic.
  2. Crear un evento del tipo "OndragOver" (solapa de eventos en el inspector de objetos):
procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;  State: TDragState; var Accept: Boolean);
begin
  Accept := true;
end;

Espero que esta información sea de ayuda. Adicionalmente podéis cargar el proyecto de ejemplo que acompaña a Lazarus (tv_add_remove.lpi) o bien ver el tutorial que se encuentra en http://users.iafrica.com/d/da/dart/Delphi/TTreeView/TreeView.html

Personalizando un TreeView

Añado esta sección debido a una consulta en el foro sobre como cambiar el color del texto en un TreeView [1].


La respuesta del usuario GetMem es que se debe establecer el valor tvoThemedDraw a False, ya que por defecto vale True.

En el Inspector de Objetos para TreeView dentro de las opciones disponibles lo encontramos en:


treeviewoptions.png


Aquí el resto de valores para las opciones que aparecen son los establecidos por defecto para un TreeView.


De esta forma nos permite personalizar más el color de la fuente que de otra manera estando tvoThemedDraw establecido al valor true utiliza por defecto el color (y la fuente) que tenga el tema visual de escritorio en uso (la otra posibilidad es deshabilitar el tema).

Esto se aplica a todos los nodos del TreeView, pero en caso de necesitar aplicar diferentes colores a los nodos el ejemplo que nos pone el usuario molly es:

    // En tiempo de creación del formulario establecemos tvoThemedDraw a false 
    // y llenamos el TreeView con 10 elementos: item 1,item 2,....,item 10 (el índice comienza por 0 para item 1).

    procedure TForm1.FormCreate(Sender: TObject);  

    var i:integer;

    begin

      TreeView1.Options := TreeView1.Options - [tvoThemedDraw]; 

      For i := 1 to 10 do TreeView1.Items.Add(nil, 'item ' + IntToStr(i));

    end;


Y asignamos al evento OnDrawItemEvent:


    // En nuestro TreeView personalizado, chequeamos si su índice de nodo es par o impar.
    // y cambia el color de texto a rojo si es impar (odd) o a verde en caso contrario.

    procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;

      Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);

    begin

      with Sender as TCustomTreeView do

        if odd(Node.Index)

        then Canvas.Font.Color:= clRed

        else Canvas.Font.Color:= clGreen;

    end;


Siendo el resultado:


customtreeview.png