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 16-07-2003
Angel Angel is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante, España
Posts: 58
Poder: 22
Angel Va por buen camino
Problemas de Inicialización de un componente

Hola a todos,

Os explico muy por encima lo que quiero hacer, tengo un componente, del cual he creado un TCollection para poder especificar ciertos valores de los campos de una tabla, y resulta que cuando creo el componente, quiero que se me inicialice esa colection con los campos que hay en una tabla. Me parece que no me explico, a ver si con un poco de código lo consigo explicar:

Código:
  { TFieldItem }
  TFieldItem = class(TCollectionItem)
  private
    FName: String;
    FColTitle: String;
    FDefaultSearch: Boolean;
    FSize: Integer;
  protected
    function GetDisplayName: String; Override;
  public
    procedure Assign(Source: TPersistent);
    procedure SetDefaultSearch (Value: Boolean);Virtual;
  published
    property Name: String read FName write FName;
    property ColTitle: String read FColTitle write FColTitle;
    property DefaultSearch:Boolean read FDefaultSearch write SetDefaultSearch;
    property Size: Integer read FSize write FSize;
  end;

  { TFieldList }
  TFieldList = class(TCollection)
  private
    FOwner: TPersistent;
    function GetItem(Index: Integer): TFieldItem;
    procedure SetItem(Index: Integer; Value: TFieldItem);
  protected
  public
    function GetOwner: TPersistent; Override;
    constructor Create(AOwner: TPersistent);
    destructor Destroy; override;
    procedure Add(AName: String; ADefaultSearch:Boolean; AColTitle: String;
                  ASize: Integer);
    procedure Clear;
    property Items[Index: Integer]: TFieldItem read GetItem write SetItem; default;
  published
  end;

  TDBViewer = class(TComponent)
  private
    FDataSet: TDataSet;
    FReturnParams: Integer;
    FReturnValues: array of Variant;
    FFieldDefs: TFieldList;
    FFormTitle : String;
    FFormWidth: Integer;
    FFormHeight:Integer;
    FEditColor: TColor;
    FGridColor: TColor;
    FDataLink: TFieldDataLink;
    function GetDataField: string;
    function GetDataSource: TDataSource;

    procedure SetDataField(const Value: string);
    procedure SetDataSource(Value: TDataSource);

  public
    procedure SetDataSet(Value: TDataSet); virtual;
    procedure SetReturnParams(Value: Integer); virtual;
    function GetDataSet: TDataSet; virtual;
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
    procedure Execute;
    function ReturnParamValues (Param:Integer):Variant;

  published
    property FieldDefs: TFieldList read FFieldDefs;
    property DataSet: TDataSet read GetDataSet write SetDataSet;
    property ReturnParams: Integer read FReturnParams Write SetReturnParams default 1;


    property FormTitle: String read FFormTitle Write FFormTitle;
    property FormHeight: Integer read FFormHeight Write FFormHeight;
    property FormWidth: Integer read FFormWidth Write FFormWidth;
    property EditColor: TColor read FEditColor Write FEditColor;
    property GridColor: TColor read FGridColor write FGridColor;

  end;
Pues bien, lo que quiero es que cuando se cree un DBViewer la propiedad FFieldDefs contenga las columnas que hay dentro del DataSet (eso en tiempo de diseño), pero que cuando se ejecute la aplicación, yo pueda acceder a esos items (y a sus valores, tanto si se han cambiando como si no).

Espero haberme explicado, y gracias a todos
Responder Con Cita
  #2  
Antiguo 16-07-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Lo que tu quieres es hacer como un DBGrid, que si no definimos ninguna columna estas se cargan dinámicamente?
Bueno, puedes husmear el código del DBGrid, si no te sirve te puedo hacer un comentario de como lo hago en los componentes "Export Suite".

Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #3  
Antiguo 16-07-2003
andres1569 andres1569 is offline
Miembro
 
Registrado: may 2003
Posts: 908
Poder: 22
andres1569 Va por buen camino
Hola:

Creo que lo más apropiado es que la creación de esos Items la realices en el método SetDataSet de TDBViewer, así se inicializan cada vez que el programador/usuario cambia el DataSet, ya sea en diseño o en ejecución (al crearse el TDBViewer no puede ser porque aún no sabemos cuál es el DataSet). Para evitar que se sobreescriban los valores cuando se lea del archivo .DFM, haces la comprobación de la variable State:
Código:
procedure TDBViewer.SetDataSet (Value: TDataSet);
begin
  if Value <> FDataSet then
  begin
    FDataSet := Value;
    if NOT (dsReading in ComponentState) then
    begin
      FFieldDefs.Clear;
      // aquí rellenas los Items tomados del DataSet
    end;
    if Value <> nil then Value.FreeNotification;
  end;
end;
__________________
Guía de Estilo
Responder Con Cita
  #4  
Antiguo 17-07-2003
Angel Angel is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante, España
Posts: 58
Poder: 22
Angel Va por buen camino
Gracias a todos, sois unas "máquinas"... La verdad es que lo terminé solucionando de una forma muy parecida a la que expuso andrés, sin embargo, ahora me encuentro con otro "problema" y es que me gustaría saber como acceder a las propiedades de la colección utilizando el botón derecho de ratón sobre el componente. Os debe decir en primer lugar que consigo crear los menús, pero no sé que poner dentro la función para mostar la misma ventana que aparece cuando pulso el botón con los tres puntos (...). El día que lo termine propondré el dejarlo para dominio público, y que alguien intente mejorarlo (quizás yo lo haya hecho un poco mal, pero es mi primer componente).

De nuevo gracias a todos........ ¡¡¡¡ Máquinas !!!!
Responder Con Cita
  #5  
Antiguo 18-07-2003
andres1569 andres1569 is offline
Miembro
 
Registrado: may 2003
Posts: 908
Poder: 22
andres1569 Va por buen camino
Hola:

En la unit colnedit.pas que encontrarás en ...DelphiX\Source\Property Editors\ está la función ShowCollectionEditor, que es la que debes llamar desde el editor de tu componente (método ExecuteVerb) para que te muestre la colección.

Esto a partir de Delphi 5. Si alguien sabe cómo conseguirlo con la versión 4, le estaré agradecido. En los fuentes no viene esa unit, y no sé dónde carajos puede estar la función que hace eso mismo.

Saludos
__________________
Guía de Estilo
Responder Con Cita
  #6  
Antiguo 18-07-2003
Angel Angel is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante, España
Posts: 58
Poder: 22
Angel Va por buen camino
Cita:
En la unit colnedit.pas que encontrarás en ...DelphiX\Source\Property Editors\ está la función ShowCollectionEditor, que es la que debes llamar desde el editor de tu componente (método ExecuteVerb) para que te muestre la colección.
No funciona, al intentarse compilar la unidad colnedit busca otra unit (la "ToolWnds") que no está por ninguna parte. A propósito, tengo Delphi 5.
Responder Con Cita
  #7  
Antiguo 18-07-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Recomendación: Arma un paquete de diseño y otro de ejecución. http://www.clubdelphi.com/foros/show...&threadid=1053
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #8  
Antiguo 18-07-2003
andres1569 andres1569 is offline
Miembro
 
Registrado: may 2003
Posts: 908
Poder: 22
andres1569 Va por buen camino
Hola Angel:

En efecto, falta esa unit que dices, ToolWnds; hace tiempo que me peleé con ese tema y lo dí por perdido, lo quería para unos componentes en Delphi 4.0, y ví que en Delphi 5 existía esa función que te dije, pero no la había probado.

Supongo que lo que dice Delphi.Com.Ar te servirá (suele acertar ). Como es una característica que te hace falta para el diseño, y Delphi usa paquetes en el IDE, supongo que se tratará de incluir el package correspondiente, aunque me queda la duda de cómo llamarlo desde tu editor de propiedades.

Si lo llegas a hacer funcionar, por favor pon un post indicando los pasos seguidos.

Saludos ¡MÁQUINAS!
__________________
Guía de Estilo
Responder Con Cita
  #9  
Antiguo 18-07-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Te garantizo que funciona, lo puedes probar bajando los mis componentes "Export Suite" de mi página que hacen lo que tu pides.


PD:
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #10  
Antiguo 21-07-2003
Angel Angel is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante, España
Posts: 58
Poder: 22
Angel Va por buen camino
Ahora si que me habeis perdido .

No, en serio, he conseguido montar los dos paquetes (aunque seguramente lo habré hecho mal ).

Vayamos por partes:
He creado un paquete de diseño llamado DsgDBViewPkg que contiene tres ficheros, DBView.dcr, DBView.pas y DBViewReg.pas (este último es el que contiene las lineas de registro del componente y el editor, algo parecido a esto: )

Código:
interface

procedure Register;

implementation

uses
  Classes,
  {$IFDEF VER130}DsgnIntf{$ELSE}DesignIntf, DesignEditors{$ENDIF},
  FiltEdit, DBView;


procedure Register;
begin
  RegisterComponents('DBViewer', [TDBViewer]);
  RegisterComponentEditor (TDBViewer,TFieldDefsProperty)
end;

end.
Todo compila, todo se instala, pero sigo sin saber como llamar al editor, ya que con ShowCollectionEditor no funciona (seguirá faltandome algo)

Sin embargo, estoy convencido que la forma en que tengo montados los paquetes esta mal, puesto que en el paquete RunDBViewPkg únicamente tengo el fichero DBView.dcr.

Como os he comentado estoy algo "perdido", y me parece que para ser mi primer componente me he pasado (a lo mejor debería haber empezado por uno más fácil, pero es el que necesito en el trabajo para hacerme la faena más cómoda)

De verdad que me sabe muy mal "molestaros", pero es que no sé por donde continuar.


Muchas gracias a todos.
Responder Con Cita
  #11  
Antiguo 21-07-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Primero te quisiera comentar que a mi parecer, y suponiendo lo que contiene cada archivo, el archivo DBView.pas no tendría que pertenecer al paquete de DesignTime, solamente al de RunTime.
Con respecto a tu problema, me gustaría que nos muestres el código del TFieldDefsProperty, que seguramente ahí esta el problema.
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #12  
Antiguo 22-07-2003
Angel Angel is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante, España
Posts: 58
Poder: 22
Angel Va por buen camino
La verdad es que no tengo ningún problema en mostraros todo el código, es más a continuación os muestro el que me habeis solicitado. Por otra parte, con lo que me comentas de no poner del Fichero DBView en el modulo de Diseño, resulta, que si no, no me deja continuar.....

Pero bueno, vamos a mostrar algo de código

en el fichero DBView.pas tengo esto:

Código:
  { TFieldItem }
  TFieldItem = class(TCollectionItem)
  private
    FName: String;
    FColTitle: String;
    FDefaultSearch: Boolean;
    FSize: Integer;
  protected
    function GetDisplayName: String; Override;
  public
    procedure Assign(Source: TPersistent);
    procedure SetDefaultSearch (Value: Boolean);Virtual;
    procedure Edit;
  published
    property Name: String read FName write FName;
    property ColTitle: String read FColTitle write FColTitle;
    property DefaultSearch:Boolean read FDefaultSearch write SetDefaultSearch;
    property Size: Integer read FSize write FSize;
  end;

  { TFieldList }
  TFieldList = class(TCollection)
  private
    FOwner: TPersistent;
  protected
  public
    function GetOwner: TPersistent; Override;
    procedure Edit;
    constructor Create(AOwner: TPersistent);
    destructor Destroy; override;
    procedure Add(AName: String; ADefaultSearch:Boolean; AColTitle: String;
                  ASize: Integer);
    procedure Clear;
    function GetItem(Index: Integer): TFieldItem;
    procedure SetItem(Index: Integer; Value: TFieldItem);
    property Items[Index: Integer]: TFieldItem read GetItem write SetItem; default;
  published
  end;

  TDBViewer = class(TComponent)
  private
    FDataSet: TDataSet;
    FReturnParams: Integer;
    FReturnValues: array of Variant;
    FFieldDefs: TFieldList;
    FFormTitle : String;
    FFormWidth: Integer;
    FFormHeight:Integer;
    FEditColor: TColor;
    FGridColor: TColor;
    FDataLink: TFieldDataLink;
    function GetDataField: string;
    function GetDataSource: TDataSource;

    procedure SetDataField(const Value: string);
    procedure SetDataSource(Value: TDataSource);

  public
    procedure Assign(Source: TPersistent);
    procedure SetDataSet(Value: TDataSet); virtual;
    procedure SetReturnParams(Value: Integer); virtual;
    function GetDataSet: TDataSet; virtual;
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
    procedure Execute;
    function ReturnParamValues (Param:Integer):Variant;
    procedure Edit;

  published
    property FieldDefs: TFieldList read FFieldDefs write FFieldDefs;
    property DataSet: TDataSet read GetDataSet write SetDataSet;
    property ReturnParams: Integer read FReturnParams Write SetReturnParams default 1;
    property FormTitle: String read FFormTitle Write FFormTitle;
    property FormHeight: Integer read FFormHeight Write FFormHeight;
    property FormWidth: Integer read FFormWidth Write FFormWidth;
    property EditColor: TColor read FEditColor Write FEditColor;
    property GridColor: TColor read FGridColor write FGridColor;
  end;

  TFieldDefsProperty = class (TComponentEditor)
    private
      procedure executeVerb (index:Integer);Override;
      function GetVerb (Index:Integer):String;override;
      function GetVerbCount:Integer; Override;
  end;


esto está en el DBViewReg.pas

Código:
unit DBViewReg;

interface

procedure Register;

implementation

uses
  Classes,
  {$IFDEF VER130}DsgnIntf{$ELSE}DesignIntf, DesignEditors{$ENDIF},
  FiltEdit, DBView;


procedure Register;
begin
  RegisterComponents('DBViewer', [TDBViewer]);
  RegisterComponentEditor (TDBViewer,TFieldDefsProperty)
end;

end.
y por último, esto es lo que tengo en el frmView.pas

Código:
type
  TfrmVisor = class(TForm)
    dsDataSource: TDataSource;
    dbGrid: TDBGrid;
    pTop: TPanel;
    gbBuscar: TGroupBox;
    cbFields: TComboBox;
    eSearch: TEdit;
    procedure FillcbFields;
    procedure Inicializar;
    procedure dbGridColEnter(Sender: TObject);



    procedure FormShow(Sender: TObject);
    procedure dbGridDblClick(Sender: TObject);
    procedure eSearchChange(Sender: TObject);
    procedure FormKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
  public
    FDataSet: TDataSet;
    FReturnParams: Integer;
    FReturnValues: array of Variant;
    FColTitles: TStringList;
    FDefaultSearch: TFieldItem;
    FFieldDefs: TFieldList;
  end;


var
  frmVisor: TfrmVisor;
Responder Con Cita
  #13  
Antiguo 22-07-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Exactamente lo que me interesa es la implementación de la clase TFieldDefsProperty.

Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #14  
Antiguo 23-07-2003
Angel Angel is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante, España
Posts: 58
Poder: 22
Angel Va por buen camino
Perdón, pero no entendí tu petición, sin embargo no creo que te sirva de mucho, pero aqui te la dejo escrita:

Código:
procedure TFieldDefsProperty.executeVerb (index:Integer);
begin
  if index=0 then      //Esta primera opción sería para poder editar los campos
  begin
  end;

  if index=1 then    //Esta segunda opción muestra una vista preliminar de los resultados.
  begin
    TDBViewer(component).Execute;
  end;
end;

function TFieldDefsProperty.GetVerb (Index:Integer):String;
begin
  if index=0 then
    result:='Edit Fields';
  if index=1 then
    result := 'Execute';
end;

function TFieldDefsProperty.GetVerbCount:Integer;
begin
  result:=2;
end;
Responder Con Cita
  #15  
Antiguo 23-07-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Bueno, veo que te falta lo mas importante, llamar al procedimiento ShowCollectionEditor en el método ExecuteVerb cuando Index = 0 ('Edit Fields'). ¡¡Te has olvidado lo que te dijo Andrés!!


Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #16  
Antiguo 24-07-2003
Angel Angel is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante, España
Posts: 58
Poder: 22
Angel Va por buen camino
Talking

Uffffff !!!

Conseguido !!!!!

Tal como comentabas en tu última respuesta, me faltaba por incluir la linea del ShowCollectionEditor y efectívamente, despues de pelearme un poco con los parámetros (3 minutos más o menos) he obtenido el resultado deseado.

Por si a alguien le puede interesar, la linea que he incluido ha sido la siguiente:

Código:
procedure TFieldDefsProperty.executeVerb (index:Integer);
begin
  if index=0 then
  begin
     // Esta es la maldita línea que faltaba.
    showcollectionEditor(self.Designer,Component,TDBViewer(component).FieldDefs,'FieldDefs');
  end;

  if index=1 then
  begin
    TDBViewer(component).Execute;
  end;
end;

Así pues, gracias a todos por vuestra inestimable ayuda, si algún día publico el componente os haré mención especial.

Supongo que con esto podemos dejar el hilo cerrado, en espera de que pueda servirle a alguien, al menos tanto como a mí. De nuevo, otra vez gracias.



Saludos
Responder Con Cita
  #17  
Antiguo 24-07-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
¿Vistes que es más interesante investigarlo que te den la respuesta?.... Y ahora: ¿No te interesa que al hacer doble click sobre tu componente se abra el editor CollectionEditor?....
Te dejo que lo investigues, si se te complica, te doy la respuesta!

Saludos...
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
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


La franja horaria es GMT +2. Ahora son las 12:26:10.


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