Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 19-11-2011
setq setq is offline
Registrado
NULL
 
Registrado: nov 2010
Posts: 6
Poder: 0
setq Va por buen camino
TTreeNode, que estoy haciendo mal

Hola, primero decir que como vengo del mundo del java aun se me siguen trabando algunas cosas de Delphi que hacia algunos años que no tocaba.

Tengo una clase TForm con un TTreeView y una clase digamos B, que recibe en el constructor el TTreeNodes del TTreeview, extrae y guarda el primer nodo del TTreeView en la variable Normas que es de tipo TTreeNode. Posteriormente se usara para poder recorrer los nodos del TTreeView desde dentro de B sin necesitar conocer el TTreeView. La intencion final es mantener la vista separada de la capa negocio, al menos esa es mi idea.

Cuando intento recorrer el arbol del TTreeView en la clase B gracias a la variable Normas que apunta a su primer nodo, obtengo datos extraños que no son los de los nodos del arbol, que se muestra correctamente en el Form con sus datos.
El nodo Normas parece apuntar a un unico nodo que contiene el valor '' y que no tiene ni hijos ni hermanos, cuando deberia apuntar a un arbol con muchos nodos y datos diferentes.
No es que haya ningun error de compilacion ni en tiempo de ejecucion, simplemente algo hay mal hecho que no alcanzo a ver pero que no hace romper al programa.

Es Delphi 2010.

Ahi les dejo el codigo con algunos comentarios a ver si alguien ve algo porque yo ya estoy mareado de tanto mirarlo, y seguro que una linea vale mas que mil palabras.

Y muchas gracias por el tiempo.


Código Delphi [-]
unit B;

type
    B = class
        Normas: TTreeNode;


        constructor Create(headNormas: TTreeNodes);
        destructor Destroy;override;
        ...

implementation

constructor B.Create(headNormas: TTreeNodes);
    begin
    Normas:=TTreeNode.Create(headNormas);
    end;
end;


---------------------------------------------------------------------


unit SDIMAIN;

type
  TSDIAppForm = class(TForm)

     treeNormas: TTreeView;
     ...
     procedure CargarTree;
     ...
     private
        FRL:B;
  end;

implementation

procedure TSDIAppForm.CargarTree;
     ...
     treeNormas.LoadFromFile(name);
     FRL:=B.Create(treeNormas.Items);
     ...

function TInterpreteFRL.getNorma(nombreNorma: String): TTreeNode;
    var
        nodo: TTreeNode;
    begin
    nodo := Normas; <<<<<<<< AQUI ES DONDE CARGA EL VALOR EXTRAÑO ''
    while (nodo <> NIL) and (nodo.Text <> nombreNorma) do
        nodo := nodo.GetNextSibling;
    getNorma := nodo;
    end;

Última edición por ecfisa fecha: 19-11-2011 a las 06:37:52.
Responder Con Cita
  #2  
Antiguo 19-11-2011
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.

Realmente no alcanzo a entender bién lo que deseas hacer por lo que no voy a sugerir nada...

Remitiendome al código, probá de este modo:
Código Delphi [-]
...
type
  TMiTreeNodes = class(TObject)
  private
    FNodes: TTreeNodes;
  public
    property Nodes: TTreeNodes read FNodes write FNodes;
    constructor Create(TNd: TTreeNodes);
    function GetThisNode(Value: string): TTreeNode;
    destructor Destroy; override;
  end;
...
implementation

constructor TMiTreeNodes.Create(TNd: TTreeNodes);
begin
  FNodes := TTreeNodes.Create(nil);
  FNodes := TNd
end;

function TMiTreeNodes.GetThisNode(Value: string): TTreeNode;
var
  N: TTreeNode;
begin
  N:= FNodes.GetFirstNode;
  while Assigned(N) and(N.Text <> Value) do
    N := N.getNextSibling;
  Result:= N
end;

...

Ejemplo
Código Delphi [-]
 TForm1 = class(TForm)
    TreeView1: TTreeView;
    ...
 private
    FRL: TMiTreeNodes;
    procedure CargarTreeNode;
  public
  end;
...

implementation
...

procedure TForm1.CargarTreeNode;
begin
  TreeView1.LoadFromFile('C:\ARCHIVO.TXT');
  FRL:= TMiTreeNodes.Create(TreeView1.Items)
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  tn: TTreeNode;
begin
  tn:= FRL.GetThisNode('UN DATO');
  if Assigned(tn) then
  begin
    ShowMessage(tn.Text);
    ...
  end
end;
...

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Última edición por ecfisa fecha: 19-11-2011 a las 12:41:55.
Responder Con Cita
  #3  
Antiguo 19-11-2011
setq setq is offline
Registrado
NULL
 
Registrado: nov 2010
Posts: 6
Poder: 0
setq Va por buen camino
Anoche estaba un poco denso de tanto rumiar el fallo, a ver si consigo resumir lo que quiero, es fácil:
Lo que necesito es cargar un árbol de nodos desde disco sin necesidad de que se muestre en pantalla. Y no conozco en Delphi una clase que me de esa funcionalidad sin tener que meter un componente en el Form. He tenido que usar el TTreeView porque es donde único dispongo del método LoadFromFile.
Mi clase no necesita mostrar el árbol en ningun componente, es una clase solo para procesar informacion de cualquier árbol que se le pase en el constructor mediante un TTreeNodes.

En cuanto al error que me daba, creo que estaba en el constructor:

Código:
Estaba haciendo esto:
N:=TTreeNode.Create(TNs);

Y he cambiado a esto:
N:=TNs.GetFirstNode;
Ahora ya me funciona. Lo ves correcto?.

En el caso A, N apunta al primer nodo del arbol TNs? o a donde? Digo 'apunta' porque pienso en punteros, al hablar de clases es correcto?. Estoy javaintoxicado.

En el caso B, N apunta al primer nodo del arbol TNs y cualquier modificacion de N afectaria a TNs?. Y en el destructor ya no debo llamar al Free creo?.


En tú código no entiendo esta parte en el constructor de TMiTreeNode:

Código:
   FNodes := TTreeNodes.Create(nil);   FNodes := TNd
Primero creas el TTreeNodes y luego los reasignas?.

Y porqué usas properties pudiendo acceder a las variables declaradas public para ello. Se que son como los getters y setters de java pero en este caso no veo la necesidad,.. o si?


Gracias, saludos.
Responder Con Cita
  #4  
Antiguo 21-11-2011
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.
Cita:
Primero creas el TTreeNodes y luego los reasignas?.
Si, en realidad podría haber enviado directamente el TreeView como argumento al constructor...
Código Delphi [-]
constructor TMiTreeNodes.Create(TNd: TTreeView);
begin
  FNodes := TTreeNodes.Create(TNd);
end;

Cita:
Y porqué usas properties pudiendo acceder a las variables declaradas public para ello. Se que son como los getters y setters de java pero en este caso no veo la necesidad,.. o si?
El uso de propiedades, si bién no es estríctamente necesario (se puede acceder a variables públicas de la clase o incluso globales), siempre es una buena práctica, ya que brinda mayor control y encapsulamiento.

Un saludo.

Edito: Me quedé pensando en lo que mencionas: "Lo que necesito es cargar un árbol de nodos desde disco sin necesidad de que se muestre en pantalla."

¿ Y no te resultaría más fácil usar un TTreeView con su propiedad Visible = False ? Lo anterior quedaría reducido a:
Código Delphi [-]
function GetThisNode(FNodes: TTreeNodes; Norma: string): TTreeNode;
var
  N: TTreeNode;
begin
  N:= FNodes.GetFirstNode;
  while Assigned(N) and(N.Text <> Norma) do
    N := N.getNextSibling;
  Result:= N;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  t: TTreeNode;
begin
  TreeView1.LoadFromFile('C:\ARCHIVO.TXT');
  t:= GetThisNode(TreeView1.Items, 'UN_NODO');
  if Assigned(t) then
   ...
end;
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Última edición por ecfisa fecha: 21-11-2011 a las 12:31:00.
Responder Con Cita
  #5  
Antiguo 21-11-2011
setq setq is offline
Registrado
NULL
 
Registrado: nov 2010
Posts: 6
Poder: 0
setq Va por buen camino
Es que no quiero usar un componente visual para manejar el arbol, me gustaria poder hacerlo por codigo solamente, es decir, sin tener que coger un componente de la paleta y pincharlo en el TForm, me explico?. Y ponerle la propiedad visible=false seria un apaño. No me gusta esa solución. De todas formas ya lo tengo solucionado usando TTreeNodes y la cosa va bien.

Pero me ha quedado una espina con el constructor que no entiendo:

Estaba haciendo esto: N:=TTreeNode.Create(TNs); //N.GetFirstNode devuelve un valor basura

Y he cambiado a esto: N:=TNs.GetFirstNode;
//N.GetFirstNode devuelve un valor correcto



En el primer caso N queda apuntando al primer nodo de TNs, o que es lo que pasa ahi para que no me de
valores correctos del TNs que le he pasado?.

Gracias por tu tiempo de nuevo.
Responder Con Cita
  #6  
Antiguo 21-11-2011
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola setq.

No tenés nada que agradecer.
Estoy un poco confundido, quizá por que no entiendo bién la lógica que deseas aplicar. Pero a ver, según entiendo en tu código, en el caso de N:=TTreeNode.Create(TNs), estas creando el objeto pero no lo inicializas en ningún momento, por eso el valor basura. Revisá este enlace donde se trata la función del parámetro Owner en la creación.

Hay algo que todavía no me queda muy claro:
Cita:
Es que no quiero usar un componente visual para manejar el arbol
Pero aquí lo estas usando:
Código Delphi [-]
type
  TSDIAppForm = class(TForm)

     treeNormas: TTreeView;
     ...
     procedure CargarTree;
     ...
     private
        FRL:B;
  end;
Es que me parece, que si deseas usar el método LoadFromFiles de TTreeView, en algún momento vas a tener que usar un TreeView y este tiene que tener un parent ...

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #7  
Antiguo 21-11-2011
setq setq is offline
Registrado
NULL
 
Registrado: nov 2010
Posts: 6
Poder: 0
setq Va por buen camino
Si, es cierto que lo estoy usando, pero como dije, es la unica forma que he visto de disponer de un metodo LoadFromFile que me cargue un arbol desde disco.

Busco algo como el TTreeNode que tenga un metodo LoadFromFile y cree un arbol (en memoria) desde disco devolviendo su root, asi no tendria que colocar TTreeViews innecesarios en formularios.

La logica que intento aplicar es la de mantener separados la logica de negocio de las vistas, y un TTreeView para mi es una Vista de algo que hay debajo (el TTreeNodes y los TTreeNode). Si pudiera manejar esos TTreeNodes sin tener que crear el TTreeView seria estupendo, pero el constructor del TTreeNode me pide un owner TTreeNodes y este a su vez me pide un TTreeView, con lo cual no salgo del circulo.

Gracias siempre.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Que estoy haciendo mal ? piolillo Internet 8 28-07-2011 17:23:24
Que estoy haciendo mal José Luis Garcí Varios 6 24-05-2011 18:45:58
Que estoy haciendo Mal esimon SQL 4 04-07-2006 21:55:25
Que estoy Haciendo mal jostrix PHP 1 01-11-2004 01:29:16


La franja horaria es GMT +2. Ahora son las 23:31:20.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi