Ir al contenido


Foto

[RESUELTO] Ayuda sobre Tcolection


  • Por favor identifícate para responder
28 respuestas en este tema

#1 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 23 mayo 2010 - 07:33

Hola compañeros estoy trabajando sobre mi componente TextMulGrid y se me platean dudas y problemas, que creo podre resolver, pero llevo varios días, leyendo, estudiando, mirando otros componentes free y no logro entender el funcionamiento de Tcolum y de este el tema de Tcolection, lo que os pido es si no es mucha molestia, el esqueleto (código) de un Dbgrid, en que se añadiera a Column una nueva propiedad llamemoles XXX tipo String, lo que necesito, es como hacer que aparezca en el inspector de objetos y como registrarla, una vez conseguido esto, el resto ya me veo capaz de ir buscándome  la vida en solucionarlo, pero sin esta parte, el componente tiene poca utilidad más.

Gracias por vuestra ayuda
  • 0

#2 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 23 mayo 2010 - 10:43

Hola Desart,
Debes estudiar las clases TCollection y TCollectionItems. La primera es el "contenedor" de la segunda. Notarás que la clase TCollection tiene los métodos para agregar, borrar, etc los TCollectionItems.

Estas clases ofrecen el esqueleto, o armazón básico. De éstas deben HEREDAR tus clases TmyCollection y TMiCollectionItems. Si tus clases no descienden de éstas no se pueda hacer lo que buscas.
Luego está la clase Cliente que hace uso de la colección. Como por ejemplo, como bien señalas está DBGrid que contiene a  a TDBGridColumns (TCollection) y ésta a TColum (TCollectionItem).
Estos clientes se valen de una propiedad PUBLICADA que mantiene a la colección. Por ejemplo la propiedad Panels de un TStatusBar.

Hay un editor genérico de colecciones. Este editor se invoca en tiempo de diseño y es el que se utiliza para generar los items. Necesariamente para conseguir que funcione tu clase descendiente de TCollection debe redefinir el método GetOwner para que pueda aparecer en el inspector de objetos.

Este método lo que hace es localizar al dueño de la colección. Si te fijas en las clases descendientes de TCollection éstas sobreescriben al método y se encargan de apuntar al dueño (la clase cliente).
La clase TCollectionItem también tiene su GetOwner, y en este caso "localiza" a su TCollection al que se insertaron.

Si examinas el código de TCollection y TCollectionItem notarás que se trata de dos "clases amigas". Ambas se comunican y envían mensajes a fin de "sincronizarse". Algunos cambios en una hace que se necesite de cambios en la otra y por ello se necesita de esta comunicación dual. Esto explica, en parte, el uso de GetOwner en la clase TCollectionItem.

Luego tienes en la clase TCollection, una batería de métodos virtuales y/o abstractos que puedes (y algunos deberás) redefinir o sobrescribir. Empecemos con Update. Update es virtual, y se encarga de actualizar la colección para propagar los cambios hacia sus items. Si necesitas alguna acción particular en tu clase descendiente en este punto. Puedes sobreescribirla.
Update se invoca cuando hay cambios por parte de un Item y necesita comunicarselo a los demás.

También está SetItemName. SetItemName, como lo indica su nombre se encarga de asociarle un Nombre al Item insertado. Está definido como virtual. Tu clase descendiente de TCollection podría sobreescribir a este método para proporcionar el nombre predeterminado adecuado a tus necesidades.

Notify es otro método virtual. En principio no es necesario sobreescribirlo. Pero de ser necesario, si necesitas implementar algún comportamiento en particular sobre las notificaciones este es lugar para hacerlo. Notify, a como está implementado en TCollection envía mensajes a sus items dependiendo de la acción realizada:
* cnAdded: se agregó un item a la colección.
* cnExtracting: el item ha sido removido pero no liberado.
* cnDeleting: el item ha sido removido Y liberado.

Notarás que se invoca a Added y a Deleting según sea el caso. Ambos métodos están marcados como deprecated. Son virtuales, si necesitas realizar alguna acción en particular para cada caso puedes redefinirlos.

Ahora vamos con TCollectionItem. Aquí también necesitarás hacer algo de trabajo... al igual que TCollection, esta clase ofrece métodos abstractos y/o virtuales que podrías (y en ciertos casos, deberás) redefinir.

Los TCollectionItem se crean y destruyen, como puedes apreciar, en los métodos Add y Clear de TCollection. Cuando éstos se crean se envian unos mensajes hacia el Item en cuestión y afectan a una propiedad importante: Collection. Esta propiedad apunta a la colección que pertenecen.

El método SetCollection, que es virtual, puede si se desea redefinirse para adaptarlo a nuevas implementaciones. Como está definido, lo que hace es establecer la colección, de una a otra.

SetIndex por defecto mueve el item de una posición a otra. Para luego invocar al método Changed. Si necesitas hacer algo extra y/o redefinir este método para nuevas implementaciones puedes hacerlo ya que es virtual.

Changed es un método protegido y se invoca automáticamente cuando algo en el Item cambia. Este método se encarga de invocar a Update de TCollection para que éste actúe en consecuencia. Es de importancia comprender tanto a Update de TCollection como a Changed de TCollectionItem.

GetDisplayName es un método virtual. Como está implementado regresa el nombre del Item. Gracias a este método es que aparece el nombre en el editor de colecciones. Con SetDisplayName se puede establecer el nombre con el que figurará en la colección. De ser necesario puedes sobreescribirlo.

Se que he sido un tanto extenso, pero a la vez he dado una explicación muy elemental (creeme ;) ). En la ayuda está documentado todo sobre TCollection, TCollectionItem. Aconsejo su lectura, además explora el código de ambas clases. Esto te ayudará a entender el concepto... luego puedes tomar a un cliente en particular y estudiar las clases descendientes de TCollection y TCollectionItem que ofrece.

No es sencillo de entenderlo a la primera. Como podrás apreciar resulta un tanto "aparatoso" porque debes redefinir algunas cosas, heredar y demás.

Espero al menos haber dado un norte.

Saludos,
  • 0

#3 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 23 mayo 2010 - 11:11

Este artículo te podrá ser de guía también.

EDITO:
Ahora recuerdo que en una ocasión el tema se discutió en CD.

Saludos,
  • 0

#4 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 23 mayo 2010 - 01:52

Gracias por tu extensa y acertada respuesta Delphius, prometo estudiar el articulo e intentar el seguimiento de tu respuesta, el problema es que llevo  días estudiando, entre otros tantos  la guia de Desarrollo par delphi 5 páginas 1126 a la 1130, los artículos de Ian Martes, componentes como nicedbgrid y Smdbgrid, otros muchos artículos y temas tocados en el foro,  Como ya he comentado otras veces, mis pocos conocimientos fueran sobre programación lineal y aunque parezca mentira, intento hacer un esquema previo y codificación liana a linea en una libreta antes de interpretarlo en el programa (no todo claro y te puedes imaginar los resultados), en cuanto a delphi lo que he aprendido ha sido de manera autodidacta, gracias a los compañeros de los foros y a muchos libros comprados, pero reconozco que mi capacidad de asimilar muchas veces choca con mis conocimientos en Basic, Dbase IV, Clipper y turbo C, como puedes ver todo programación lineal.

        Lo que si se es que cuando veo un código donde sin meter nada más que lo que intento estudiar, suelo asimilar mejor su manera de funcionar, reconozco que no aprendo el por que la mayoría de las veces pero si aprendo de su uso, por eso es por lo que pido el esqueleto de un dbgrid, cuya única nueva propiedad XXX dentro de tColumn, me permitiría asimilar el uso de la Tcolletion, donde me estoy equivocando y por que no me sale  en el código que le he añadido al ExtMulGrid, luego podría aplicar a este código, todos las ideas que tengo en mi mente, como por ejemplo que el grid permita campos encriptados con una función predefinida que se muestre encriptados o desencriptados.

  Mi otro problema es que salgo de casa a las  6,30 para dejar a mi hija en el instituto, regreso como muy temprano de lunes a viernes a alas 4.00, los viernes a las 2.00, tengo que llevar tres días en semana a mi hija a una actividad extra escolar, dedicarle tiempo a la reformas de casa, el programa de la empresa, y tiempo para los míos, después de eso procuro ver algo de cine y cuando queda tiempo los fines de semana a la programación. No me quejo es la vida que yo he elegido, pero si es verdad que no puedo dedicarle todo el tiempo que me apetecería

  • 0

#5 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 23 mayo 2010 - 04:14

Hola,

De mi parte no hay apuro Desart, tu sigue... a tu ritmo y en cuanto el tiempo y tus obligaciones te lo permita (supongo que tu no tienes apuro).

De todas formas al tema lo deberás (o quizá mejor dicho: deberías) analizar con tranquilidad. No es fácil asimilarlo (al menos para mí). Lo que expuse es un resumen de lo poco que aprendí y traducí de la ayuda sobre TCollection y TCollectionItem; como yo estoy estudiando (bueno... ahorita esto está en stand-by) la VCL al llegar a TParam y TParams me tuve que ver obligado a ver las clases TCollection y TCollectionItem.
Yo a eso lo estuve analizando y viendo por casi un mes. Me quedé medianamente conforme: lo suficiente como para entender más o menos su interrelación y uso en lo que respecta para el caso de TParam y TParams.

Mucho no te sabría decir, y de lo que he explorado por la VCL el tema tiene sus mañas. En términos conceptuales (visto desde el plano de los patrones y el uso de técnicas OO) es simple: se trata de una agregación compartida o simplemente agregación. Pero internamente, en términos de código, es denso porque se tiene que analizar a ambas clases en conjunto.

Cuando se entiende el concepto y se ve el código de clases clientes y como ponen en uso las colecciones (grids, statusbar, datasets, TListView, entre otros) se observa que las clases son muy estables y no tienen demasiada variaciones: todas comparten un denominador común y eso es posible ya que TCollection y TCollectionItem ya tienen la estructura formada y esta NO CAMBIA: sólo hay que hacer uso de ellas, extendiéndolas añadiendo nuestras clases y sobreescribiendo los métodos necesarios.

Ve con calma, yo no te apuro. No te sientas amenazado. Ya sabes, si te trabas, ¡aquí estaremos! :)

Saludos,
  • 0

#6 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 24 mayo 2010 - 12:58

Gracias Delphius :cheesy:
  • 0

#7 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 25 mayo 2010 - 01:36

Hola compañeros he estado mirando lo links expuestos arriba  usando ademas este otrohttp://delphi.about....t/uc083101d.htm  y en la Página de IGriega el articulo sobre las coleciones, he ido montando este código


delphi
  1. unit DBGridPrueba1;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils, Classes, Controls, Grids, DBGrids;
  7.  
  8. type
  9.   TOurCollectionItem = class(TCollectionItem)
  10.   private
  11.     FSomeValue : String;
  12.   protected
  13.     function GetDisplayName : String; override;
  14.   public
  15.     procedure Assign(Source: TPersistent); override;
  16.   published
  17.     property SomeValue : String
  18.       read FSomeValue
  19.       write FSomeValue;
  20.   end;
  21.  
  22.   TOurCollection = class(TCollection)
  23.   private
  24.     FOwner : TComponent;
  25.     function GetItem(Index: Integer): TOurCollectionItem;
  26.     procedure SetItem(Index: Integer; Value:TOurCollectionItem);
  27.   protected
  28.     function GetOwner : TPersistent; override;
  29.     procedure Update(Item: TOurCollectionItem);
  30.   public
  31.     constructor Create(AOwner : TComponent);
  32.     function Add : TOurCollectionItem;
  33.     function Insert(Index: Integer): TOurCollectionItem;
  34.     property Items[Index: Integer]: TOurCollectionItem
  35.       read GetItem
  36.       write SetItem;
  37.   end;
  38.  
  39.   TCollectionComponent = class(TComponent)
  40.   private
  41.     FOurCollection : TOurCollection;
  42.     procedure SetOurCollection(const Value:
  43.       TOurCollection);
  44.   public
  45.     constructor Create(AOwner : TComponent); override;
  46.     destructor Destroy; override;
  47.   published
  48.     property OurCollection : TOurCollection
  49.       read FOurCollection
  50.       write SetOurCollection;
  51.   end;
  52.  
  53.  
  54. type
  55.   TDBGridPruebas = class(TDBGrid)
  56.   private
  57.     { Private declarations }
  58.   protected
  59.     { Protected declarations }
  60.   public
  61.     { Public declarations }
  62.   published
  63.     { Published declarations }
  64.   end;
  65.  
  66. procedure Register;
  67.  
  68. implementation
  69.  
  70. procedure Register;
  71. begin
  72.   RegisterComponents('PRUEBAS', [TDBGridPruebas]);
  73. end;
  74.  
  75. procedure TOurCollectionItem.Assign(Source: TPersistent);
  76. begin
  77.   if Source is TOurCollectionItem then
  78.     SomeValue := TOurCollectionItem(Source).SomeValue
  79.   else
  80.     inherited; //raises an exception
  81. end;
  82.  
  83. function TOurCollectionItem.GetDisplayName: String;
  84. begin
  85.   Result := Format('Item %d',[Index]);
  86. end;
  87.  
  88. constructor TOurCollection.Create(AOwner: TComponent);
  89. begin
  90.   inherited Create(TOurCollectionItem);
  91.   FOwner := AOwner;
  92. end;
  93.  
  94. function TOurCollection.GetOwner: TPersistent;
  95. begin
  96.   Result := FOwner;
  97. end;
  98.  
  99. constructor TCollectionComponent.Create(AOwner: TComponent);
  100. begin
  101.   inherited;
  102.   FOurCollection := TOurCollection.Create(Self);
  103. end;
  104.  
  105. destructor TCollectionComponent.Destroy;
  106. begin
  107.   FOurCollection.Free;
  108.   inherited;
  109. end;
  110.  
  111. procedure TCollectionComponent.SetOurCollection(
  112.   const Value: TOurCollection);
  113. begin
  114.   FOurCollection.Assign(Value);
  115. end;
  116.  
  117. function TOurCollection.GetItem(Index: Integer): TOurCollectionItem;
  118. begin
  119.     result := inherited Items[Index] as TOurCollectionItem;
  120. end;
  121.  
  122. function TOurCollection.Add: TOurCollectionItem;
  123. begin
  124.   result := inherited Add as TOurCollectionItem;
  125. end;
  126.  
  127. procedure TOurCollection.SetItem(Index: Integer; Value: TOurCollectionItem);
  128. begin
  129.   inherited Items[Index] := Value;
  130. end;
  131.  
  132.  
  133. function TOurCollection.Insert(Index: Integer): TOurCollectionItem;
  134. begin
  135.   inherited Insert(Index);
  136. end;
  137.  
  138. procedure TOurCollection.Update(Item: TOurCollectionItem);
  139. begin
  140.     inherited Update(Item);
  141. end;
  142.  
  143. end.



Pero aun Así no me sale en el Tcolumn la propiedad expuesta FSomeValue,  si podeis ayudarme.

  • 0

#8 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 25 mayo 2010 - 01:46

Hola

No se mucho de esto pero.... no le hace falta un procedure SetSomeValue ?

Algo así



delphi
  1. type
  2.   TOurCollectionItem = class(TCollectionItem)
  3.   private
  4.     FSomeValue : String;
  5.     procedure SetSomeValue(const value:string);
  6.   protected
  7.     function GetDisplayName : String; override;
  8.   public
  9.     procedure Assign(Source: TPersistent); override;
  10.   published
  11.     property SomeValue : String read FSomeValue  write SetSomeValue;
  12.   end;
  13.  
  14. procedure TOurCollection.SetSomeValue(const Value: string);
  15. begin
  16.   FSomeValue := Value;
  17. end;



Salud OS
  • 0

#9 Héctor Randolph

Héctor Randolph

    501st Legion

  • Moderadores
  • PipPipPip
  • 664 mensajes
  • LocationMéxico

Escrito 25 mayo 2010 - 02:04

Hola Desart

Siguiendo tu código, creaste una colección (TOurCollection ) y definiste los elementos de la colección (TOurCollectionItem ) esto es correcto. Sin embargo, no veo en dónde los estás utilizando, es decir, tienes un derivado de TDBGrid (TDBGridPruebas ) e incluso lo registraste como componente para que aparezca en la paleta de Delphi, pero no has hecho nada con él.

Tal vez lo que requieres es definir una nueva propiedad para que aparezca en el editor algo como esto:



delphi
  1. type
  2.   TDBGridPruebas = class(TDBGrid)
  3.   private
  4.     { Private declarations }
  5.     FColumnas:TOurCollection
  6.   protected
  7.     { Protected declarations }
  8.   public
  9.     { Public declarations }
  10.     constructor Create(AOwer: TComponent);override;
  11.     destructor Destroy;
  12.   published
  13.     { Published declarations }
  14.     Columnas:TOurCollection read FColumnas write FColumnas;
  15.   end;
  16. implementation
  17.  
  18. procedure TDBGridPruebas.Create(AOwer: TComponent);
  19. begin
  20.   inherited Create(AOwner);
  21.   FColumnas:=TOurCollection.Create;
  22. end;
  23.  
  24. procedure TDBGridPruebas.Destroy;
  25. begin
  26.   FreeAndNil(FColumnas);
  27.   inherited Destroy;
  28. end;



El código que estoy poniendo lo hago de memoria y no lo he probado pero con algunos ajuste debería funcionar.

Saludos

  • 0

#10 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 25 mayo 2010 - 04:26

Hola Desart,
No vi bien el código, hoy estoy bastante dormido. Pero de lo que aprecio el TCollectionComponent está sobrando.

El asunto es:
1. Diseñar una clase que descienda de TCollection y sobreescribir los métodos.
2. Diseñar una clase que descienda de TCollectionItem y sobrescribir los métodos.
3. Diseñar la clase cliente (la que hará uso de los TCollection... en tu caso tu nuevo DBGrid) y añadir una propiedad PUBLICADA que haga referencia al TCollection que diseñaste.

Si me das el tiempo me pongo a ver con calma bien el código y ver en que más está fallando.

Saludos,
  • 0

#11 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 29 mayo 2010 - 07:04

Hola Compañeros Creo Que lo he resuelto  <:o) (y) *-), estudiando El código del DbgridCheck y El de Smdbgrid, he llegado a este código, no lo doy por cerrado, por si encontráis algo que este mal o a depurar. Quedo a la Espera de los Comentarios


delphi
  1. unit DBGridPrueba1;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils, Classes, Controls, Grids, DBGrids, Graphics;
  7. //****************************************************************************//
  8. type
  9.   TMiColumn = class(TCoLumn)
  10.   private
  11.     FSomeValue : String;
  12.     FValueLow: Integer;
  13.     FCcolorValueLow: Tcolor;
  14.     FChekValueLow: Boolean;
  15.     procedure SetSomeValue(Value: string);
  16.     procedure SetColorValueLow(Value: Tcolor);
  17.     procedure SetValueLow(Value:Integer);
  18.     procedure SetCheckValueLow(Value:Boolean);
  19.   protected
  20.   public
  21.     constructor Create(Collection:TCollection); override;
  22.     destructor Destroy; override;
  23.   published
  24.     property SomeValue :    String  read FSomeValue      write SetSomeValue;
  25.     property ValueLow  :    Integer  read FValueLow        write SetValueLow      default 0;
  26.     property ColorValueLow:  Tcolor  read FCcolorValueLow  write SetColorValueLow  default clYellow;
  27.     property CheckValueLow:  Boolean  read FChekValueLow    write SetCheckValueLow  default False;
  28.   end;
  29. //****************************************************************************//
  30.   TMiGridColumns  = class(TDBGridColumns)
  31.   private
  32.     function GetColumn(Index: Integer): TMiColumn;
  33.     procedure SetColumn(Index: Integer; Value: TMiColumn);
  34.   protected
  35.   public
  36.     function Add: TMiColumn;
  37.     property Items[Index: Integer]: TMiColumn read GetColumn write SetColumn; default;
  38.   end;
  39. //****************************************************************************//
  40. type
  41.   TDBGridPruebas = class(TDBGrid)
  42.   private
  43.     { Private declarations }
  44.     function GetColumns: TMiGridColumns;
  45.     procedure SetColumns(Value: TMiGridColumns);
  46.   protected
  47.     { Protected declarations }
  48.     function CreateColumns: TDBGridColumns; override;
  49.   public
  50.     { Public declarations }
  51.     constructor Create(AOwner : TComponent); override;
  52.     destructor Destroy;
  53.     property Columns: TMiGridColumns read GetColumns write SetColumns;
  54.   published
  55.     { Published declarations }
  56.   end;
  57.  
  58. procedure Register;
  59.  
  60. implementation
  61.  
  62. procedure Register;
  63. begin
  64.   RegisterComponents('PRUEBAS', [TDBGridPruebas]);
  65. end;
  66.  
  67. {TMiculumn}
  68. constructor TMiColumn.Create(Collection: TCollection);
  69. begin
  70.   inherited Create(Collection);
  71.   FSomeValue:='';
  72.   FValueLow:=0;
  73.   FCcolorValueLow:=clYellow;
  74.   FChekValueLow:=False;
  75. end;
  76.  
  77. Destructor TMiColumn.Destroy;
  78. begin
  79.   inherited
  80. end;
  81.  
  82. procedure TMiColumn.SetSomeValue(Value: string);
  83. begin
  84.   if FSomeValue<>Value then FSomeValue:=Value;
  85. end;
  86.  
  87. procedure TMiColumn.SetColorValueLow(Value: Tcolor);
  88. begin
  89.   if FCcolorValueLow<>Value then FCcolorValueLow:=Value;
  90. end;
  91.  
  92. procedure TMiColumn.SetValueLow(Value: Integer);
  93. begin
  94.   if FValueLow<>Value then FValueLow:=Value;
  95. end;
  96.  
  97. procedure TMiColumn.SetCheckValueLow(Value: Boolean);
  98. begin
  99.   if  FChekValueLow<>Value then  FChekValueLow:=Value;
  100. end;
  101.  
  102. {TMiGridColumns}
  103. function TMiGridColumns.Add: TMiColumn;
  104. begin
  105.   Result := TMiColumn(inherited Add);
  106. end;
  107.  
  108. function TMiGridColumns.GetColumn(Index: Integer): TMiColumn;
  109. begin
  110.   Result := TMiColumn(inherited Items[Index]);
  111. end;
  112.  
  113. procedure TMiGridColumns.SetColumn(Index: Integer; Value: TMiColumn);
  114. begin
  115.   Items[Index].Assign(Value);
  116. end;
  117.  
  118. {TDBGridPruebas}
  119. constructor TDBGridPruebas.Create(AOwner : TComponent);
  120. begin
  121.   inherited Create(AOwner);
  122. end;
  123.  
  124. destructor TDBGridPruebas.Destroy;
  125. begin
  126.   inherited Destroy;
  127. end;
  128.  
  129. function TDBGridPruebas.GetColumns: TMiGridColumns;
  130. begin
  131.   Result := TMiGridColumns(inherited Columns)
  132. end;
  133.  
  134. procedure TDBGridPruebas.SetColumns(Value: TMiGridColumns);
  135. begin
  136.   TMiGridColumns(Columns).Assign(Value)
  137. end;
  138.  
  139. function TDBGridPruebas.CreateColumns: TDBGridColumns;
  140. begin
  141.     Result := TDBGridColumns.Create(Self, TMiColumn);
  142. end;
  143. end.



  • 0

#12 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 01 junio 2010 - 04:19

Hola Desart,
Desconozco las clases DbgridCheck y Smdgrid, pero de lo que estuve viendo de tu código y de lo que ví en el código del DBGrid, creo que podría funcionar.

No lo he probado aún, pero de lo veo al principio me temía algunos goteos de memoria, y alguna que otra mala asignación de los items en tu colección e incluso en la vinculación de tu clase TCollection. Pero revisando mejor me he dado cuenta de que estás invocando a los respectivos métodos de su padre cuando es necesario con inherited.

Yo a esto, como dije antes, mucho no se... y requiere de mucha visión y análisis. A mi todavía se me hace un lío. Lo que me preocupa es el vínculo entre tu clase TMiGridColumns y tu Grid. Supuestamente gracias a que sobreescribes el método CreateColumns para devolver las clases adecuadas y asociarlo al Grid bastaría... pero no estoy totalmente seguro.

Me mareo para entenderle la mano  :  :(, y eso se debe a que cuando lo estudié al concepto no lo puse en práctica sólo lo he revisado como para captar mejor el uso de TParam y TParams.

De la revisión intuyo que podría, y debería, funcionar; pero no puedo quitarme la sensación de incomodidad por mi falta de práctica del concepto. ¿Te aparece el editor de colecciones? ¿Puedes ver bien la propiedad Items? ¿Que clase figura en el editor? La que definiste o su padre... Si esto te da bien OK, entonces es de suponer que lo demás anda bien.... Ya que las clases en las que te basaste hacen casi todo el trabajo y éstas ya tienen los controles y asignaciones bien elaborados (sobre todo la de creación y liberación, que es lo que me preocupa).

Saludos,
  • 0

#13 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 02 junio 2010 - 01:12

Gracias Delphius, esta probado y funciona, el problema lo tengo ahora al integrar las nuevas funciones en el dbgrid, con la llamada a las propiedades y tambien con el repintado del dbgrid.

  El problema  con las propiedades usos Self(del TdbgridPruebas).Columnus[Column.id].FSomeValue, por ejemplo y funciona bien con un grid, cuando pongo dos en el mismo form me da un error, no te lo pongo ahora por que estoy en la empresa, en cuanto a lo segundo estoy bloqueado.

  He visto en varios Componentes que antes de las propiedades y otras cases hacen

        TDBGridPruebas = Class;  //<--- Aqui me marca un error


  y luego mucho más abajo se pone la creación correcta

        TDbgridPruebas = class(TDbGrid);  //(2)


El problema es que no se por que me marca un error, no se si es un problema de uses ya que tengo

              Windows, SysUtils, Messages, Classes, Controls, Forms, StdCtrls,
              Graphics, Grids, DBCtrls, Db, Menus, ImgList, DBGrids, Variants;

O si el problema esta en la creación (2)

  • 0

#14 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 07 junio 2010 - 01:22

Hola compañeros persiste el error cuando entro en columnas del gris, mostrandome un indice mayor, expongo este hilo, por si podeis ayudarme
  • 0

#15 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 07 junio 2010 - 04:58

Hola Desart,
Lamentablemente en esto no te sabría ayudar. :(

Mis conocimientos no llegan hasta eso, y no dispongo del suficiente tiempo como para sentarme tranquilo a pensar.

Ojalá alguien más pueda darte una mano. Disculpa.

Saludos,




  • 0

#16 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 11 junio 2010 - 01:55

hola compañeros, sigo con el problema, pero decididamente el problema esta en el Self. Pero mi duda es la siguiente, en la mayoría de los componentes de Grids que he mirado, existe


delphi
  1. TNombreGrid = Class;



Luego más adelante se implementa como



delphi
  1. TNombreGrid = Class(TCumstomGrid)



Pero si lo intento me da un error, en la primera declaración de clase, pero no se por que, si por falta de un uses, o por mala declaración, no sé la verdad, si podéis echarme una mano os lo agradezco.

  • 0

#17 andres1569

andres1569

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 431 mensajes

Escrito 15 junio 2010 - 06:03

Hola Jose Luís, contestando a los problemas que te surgen:

1º) Lo de declarar dos veces la misma clase, que has copiado de otros componentes. Esto se llaman declaraciones forward. Es útil cuando declaras dos o más clases en las que una hace referencia a otra en su declaración (variables, métodos o propiedades), y a la vez la otra hace referencia a la primera. Esto tiene el problema de que siempre habrá una que vaya en primer lugar, y ésta no puede saber de la existencia de la segunda; ¿la solución? emplear las declaraciones forward, en que declaras una clase en la parte de arriba simplemente para darla a conocer, y más adelante ya la desarrollas, volviéndola a declarar y especificando ya de qué clase hereda y toda la serie de métodos y propiedades.

Aunque lo hayas tomado de otros componentes deberías plantearte si te hace falta realmente: lo puedes saber muy fácilmente, eliminas la primera declaración (TDBGridPruebas = Class;) y si te salta un error en otra clase diciendo que no conoce a TDBGridPruebas entonces es que sí hacía falta esa declaración previa. Y en caso de que te haga falta, veamos el error que te salta:



delphi
  1. Type
  2.   TDBGridPruebas = Class; //<--- Aqui me marca un error
  3.  
  4. y luego mucho más abajo se pone la creación correcta
  5.  
  6. Type
  7.   TDbgridPruebas = Class(TDBGrid); //(2)



He investigado ese error y se produce porque entre una y otra declaración vuelves a meter una cláusula Type. Esto no me había pasado nunca hasta que lo he comprobado, por lo visto éso causa un error del tipo "class TDBGridPruebas is not yet completely defined", debe ser que las declaraciones forward precisan estar definidas en el ámbito de una sola sección Type. Como dicha cláusula Type está de sobra, la puedes eliminar y no te saltará el error.

2º) Sobre repintados del DBGridPruebas. No sé exactamente qué es lo que te pueda estar fallando, o que eches de menos, pero me imagino que quizás al asignar un valor de una de las columnas (TMiColumn) éste no lo ves reflejado inmediatamente en pantalla. Para lograrlo, los métodos Set que utilizas para asignar propiedades deben hacer algo más que fijar la propiedades, además deben notificarlo. Te pongo un ejemplo de cómo quedaría uno de esos métodos y ya adaptas tu los otros:



delphi
  1. procedure TMiColumn.SetColorValueLow(Value: Tcolor);
  2. begin
  3.   if FCcolorValueLow <> Value then
  4.   begin
  5.     FCcolorValueLow := Value;
  6.     Changed(False);
  7.   end; 
  8. end;



Ahora, cuando el valor asignado es diferente al que había, aparte de asignar el nuevo valor, se llama al método Changed. Éste es un método de la clase TCollectionItem que se encarga de notificar a la colección que un Item ha cambiado, y la colección ya se encarga de notificárselo a su propietario (GetOwner) para que se repinte o haga lo que crea conveniente (de esto ya se encarga la misma clase TDBGridColumns en su método Update que avisa al Grid padre de que debe repintarse).

3º) Accesos fallidos a cada columna mediante Self(del TdbgridPruebas).Columns[Column.id].FSomeValue.

El problema aquí es el siguiente: cuando sobreescribes el método CreateColumns en la clase TDBGridPruebas, debes crear una colección del tipo que a tí te interesa, en tu caso TMiGridColumns. Ese método ya está pensado para facilitar la tarea al porogramador que, como tú, quiere crear su propio tipo de colección de columnas, sin usar el que viene por defecto. Por lo tanto, ahí debes crear una instancia de tu tipo, no del que trae Delphi:



delphi
  1. function TDBGridPruebas.CreateColumns: TDBGridColumns;
  2. begin
  3.     Result := TDBGridColumns.Create(Self, TMiColumn);
  4. end;
  5.  
  6. Sustituir por:
  7.  
  8. function TDBGridPruebas.CreateColumns: TDBGridColumns;
  9. begin
  10.     Result := TMiGridColumns.Create(Self, TMiColumn);
  11. end;



Puesto que TMiGridColumns tiene una propiedad Columns que devuelve elementos del tipo TMiColumn, ahora cuando accedas a dichas columnas mediante Self(del TDBGridPruebas).Columns[Column.id].SomeValue, accederá a una columna del tipo deseado y no debería darte dicho error (aunque no lo he probado, creo que no debes tener problemas). Por cierto, puedes eliminar ya lo de Self dejando simplemente Columns[Column.id].SomeValue.

Saludos

  • 0

#18 andres1569

andres1569

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 431 mensajes

Escrito 15 junio 2010 - 07:04

Hola:

Otra cosa que he visto y que puede que esté dando problemas es que declaras una propiedad public Columns en la clase TDBGridPruebas, con sus respectivos métodos de lectura y escritura GetColumns y SetColumns. Esta propiedad oculta a la propiedad del mismo nombre de la clase ancestra TDBGrid, que allí es published, por lo que me temo que origina un conflicto entre las columnas que creas en diseño (las del TDBGrid) y las que accedes en ejecución (las del TDBGridPruebas), ya que se comportan como propiedades distintas.

Una vez que usas el método CreateColumns para crear tu propia instancia de columnas, tal como te comenté en mi anterior mensaje, esto es suficiente puesto que la clase TDBGrid asigna la instancia que tú creas a una variable interna llamada FColumns y ya se encarga de gestionarla para leerla y escribirla, y que aparezca en el Object Inspector, así que mi consejo es que no declares de nuevo ninguna propiedad Columns y que elimines también los dos métodos GetColumns y SetColumns.

Resumiendo, basta con llamar a CreateColumns para que todo funcione correctamente, dejando que la clase TDBGrid haga el resto.

Saludos
  • 0

#19 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 15 junio 2010 - 11:17

Muchas gracias Andres1569, te prometo que esta semana estudio lo que me dices y te comento en este foro como me fue.
  • 0

#20 Desart

Desart

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 715 mensajes
  • LocationEspaña

Escrito 16 junio 2010 - 11:09

Hola andres1569, lo he intentado y  sigo frustrado, como tigre en una caja de zapatos, he añadido algo, más estudiado del TSMDBGRID
pero aún así nada. Te expongo el código a ver si tú o alguno de los compañeros sabe cual es el programa.


delphi
  1. unit DBGridPrueba2;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils, Classes, Controls, Grids, DBGrids, Graphics, Windows, Variants, DB, Dialogs;
  7. //****************************************************************************//
  8.  
  9. type
  10.   TxDBGridPruebas= class;
  11.   TXValueType = (ValueInteger,ValueFloat);
  12.   TxMiColumn = class(TCoLumn)
  13.   private
  14.     FSomeValue : String;
  15.     FXValueType: TXValueType;  //Elegimos tipo de valor Integer o Float
  16.     FCheckValueType: Boolean;  //Si queremos chequear que el campo sea igual al tipo elegido
  17.     FValueLow: String;      //Valor inferior o igual
  18.     FCcolorValueLow: Tcolor;    //Color PAra este valor
  19.     FChekValueLow: Boolean;    //Activar
  20.     FValueMax: String;
  21.     FCcolorValueMax: Tcolor;
  22.     FChekValueMax: Boolean;
  23.     FCcolorValueMid: Tcolor;
  24.     FChekValueMid: Boolean;
  25.     procedure SetSomeValue(Value: string);
  26.     procedure SetColorValueLow(Value: Tcolor);
  27.     procedure SetValueLow(Value:string);
  28.     procedure SetCheckValueLow(Value:Boolean);
  29.     procedure SetColorValueMax(Value: Tcolor);
  30.     procedure SetValueMax(Value:string);
  31.     procedure SetCheckValueMax(Value:Boolean);
  32.     procedure SetColorValueMid(Value: Tcolor);
  33.     procedure SetCheckValueMid(Value:Boolean);
  34.     procedure SetXValueType(Value: TXValueType);
  35.     procedure SetCheckValueType(Value: Boolean);
  36.   protected
  37.     function GetGrid: TxDBGridPruebas;
  38.   public
  39.     constructor Create(Collection:TCollection); override;
  40.     destructor Destroy; override;
  41.     procedure Assign(Source: TPersistent); override;
  42.   published
  43.     property SomeValue :    String      read FSomeValue      write SetSomeValue;
  44.     property ValueLow  :    string      read FValueLow        write SetValueLow;
  45.     property ColorValueLow:  Tcolor      read FCcolorValueLow  write SetColorValueLow  default clRed;
  46.     property CheckValueLow:  Boolean      read FChekValueLow    write SetCheckValueLow  default False;
  47.     property ValueMax  :    string      read FValueMax        write SetValueMax;
  48.     property ColorValueMax:  Tcolor      read FCcolorValueMax  write SetColorValueMax  default clGreen;
  49.     property CheckValueMax:  Boolean      read FChekValueMax    write SetCheckValueMax  default False;
  50.     property ColorValueMid:  Tcolor      read FCcolorValueMid  write SetColorValueMid  default clYellow;
  51.     property CheckValueMid:  Boolean      read FChekValueMid    write SetCheckValueMid  default False;
  52.     property XValueType:    TXValueType  read FXValueType      write SetXValueType    default ValueInteger;
  53.     property ChekValueType:  Boolean      read FCheckValueType  write SetCheckValueType default False;
  54.   end;
  55. //****************************************************************************//
  56. // TxDBGridPruebas = class;
  57.   TxMiGridColumns  = class(TDBGridColumns)
  58.   private
  59.     function GetColumn(Index: Integer): TxMiColumn;
  60.     procedure SetColumn(Index: Integer; Value: TxMiColumn);
  61.   protected
  62.   public
  63.     function Add: TxMiColumn;
  64.     property Items[Index: Integer]: TxMiColumn read GetColumn write SetColumn; default;
  65.   end;
  66. //****************************************************************************//
  67.  
  68.   TxDBGridPruebas = class(TDBGrid)
  69.   private
  70.     { Private declarations }
  71. //    function GetColumns: TxMiGridColumns;
  72. //    procedure SetColumns(Value: TxMiGridColumns);
  73.   protected
  74.     { Protected declarations }
  75.     function CreateColumns: TDBGridColumns; override;
  76.     procedure DrawColumnCell(const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); override;
  77.   public
  78.     { Public declarations }
  79.     constructor Create(AOwner : TComponent); override;
  80.     destructor Destroy;
  81.  
  82.   published
  83.     { Published declarations }
  84. //      property Columns: TxMiGridColumns read GetColumns write SetColumns;
  85.   end;
  86.  
  87. procedure Register;
  88.  
  89. implementation
  90.  
  91.  
  92. procedure Register;
  93. begin
  94.   RegisterComponents('PRUEBAS', [TxDBGridPruebas]);
  95. end;
  96. //-----------------------------------------------------------------------------
  97. //*************************************************[ PAra los cambios del Ddbgrid  ]******
  98. //
  99. //-----------------------------------------------------------------------------
  100. Procedure MixChange(Value:Boolean);
  101. begin
  102.     if Value=True then  TDBGrid(TxDBGridPruebas).Invalidate;
  103. end;
  104.  
  105. {TMiculumn}
  106. constructor TxMiColumn.Create(Collection: TCollection);
  107. begin
  108.   inherited Create(Collection);
  109.   FSomeValue:='';
  110.   FValueLow:='0';
  111.   FCcolorValueLow:=clRed;
  112.   FChekValueLow:=False;
  113.   FValueMax:='0';
  114.   FCcolorValueMax:=clGreen;
  115.   FChekValueMax:=False;
  116.   FCcolorValueMid:=clYellow;
  117.   FChekValueMid:=False;
  118.   FCheckValueType:=False;
  119. end;
  120.  
  121. Destructor TxMiColumn.Destroy;
  122. begin
  123.   inherited
  124. end;
  125.  
  126. procedure TxMiColumn.Assign(Source: TPersistent);
  127. var              //Mirado y copuiado de Smdbgrid y mitecGrid
  128. colSource: TxMiColumn;
  129. begin
  130.   inherited Assign(Source);
  131.  
  132.   if Source is TxMiColumn then
  133.   begin
  134.     colSource := TxMiColumn(Source);
  135.     if Assigned(Collection) then
  136.       Collection.BeginUpdate;
  137.     try
  138.       ValueLow := colSource.ValueLow;
  139.       CheckValueLow:= colSource.CheckValueLow;
  140.       ColorValueLow:=colSource.ColorValueLow;
  141.       SomeValue:= colSource.SomeValue;
  142.       XValueType:= colSource.XValueType;
  143.       ChekValueType:= colSource.ChekValueType;
  144.       ValueMax := colSource.ValueMax;
  145.       CheckValueMax:= colSource.CheckValueMax;
  146.       ColorValueMax:=colSource.ColorValueMax;
  147.       ValueLow := colSource.ValueLow;
  148.       CheckValueMid:= colSource.CheckValueMid;
  149.       ColorValueMid:=colSource.ColorValueMid;
  150.     finally
  151.       if Assigned(Collection) then
  152.         Collection.EndUpdate;
  153.     end;
  154.   end;
  155. end;
  156.  
  157. function TxMiColumn.GetGrid;    //Mirado y copuiado de Smdbgrid y mitecGrid
  158. begin
  159.     if Assigned(Collection) and (Collection is TxMiGridColumns) then
  160.     Result := TxDBGridPruebas(inherited Grid)
  161.   else
  162.     Result := nil;
  163. end;
  164.  
  165. procedure TxMiColumn.SetSomeValue(Value: string);
  166. begin
  167.   if FSomeValue<>Value then FSomeValue:=Value;
  168. //  TDBGrid(TDBGridPruebas).Invalidate;
  169. Changed(False);
  170. end;
  171.  
  172. procedure TxMiColumn.SetXValueType(Value: TXValueType);
  173. begin
  174.   if FXValueType<>value then FXValueType:=Value;
  175. //  TDBGrid(TxDBGridPruebas).Invalidate;
  176. Changed(False);
  177. end;
  178. //*********************LOW
  179. procedure TxMiColumn.SetColorValueLow(Value: Tcolor);
  180. begin
  181.   if FCcolorValueLow<>Value then FCcolorValueLow:=Value;
  182.   Changed(False);
  183. //    FChekValueLow:=False;
  184. end;
  185.  
  186. procedure TxMiColumn.SetValueLow(Value: string);
  187. begin
  188.   if FValueLow<>Value then FValueLow:=Value;
  189.   FChekValueLow:=False;
  190.   Changed(False);
  191. end;
  192.  
  193. procedure TxMiColumn.SetCheckValueLow(Value: Boolean);
  194. begin
  195.   if  FChekValueLow<>Value then  FChekValueLow:=Value;
  196.   Changed(False);
  197. //  TDBGrid(TDBGridPruebas).Invalidate;
  198. end;
  199. //********************MAX
  200. procedure TxMiColumn.SetColorValueMax(Value: TColor);
  201. begin
  202.   if FCcolorValueMax<>Value then FCcolorValueMax:=Value;
  203. //    FChekValueMax:=False;
  204. Changed(False);
  205. end;
  206.  
  207. procedure TxMiColumn.SetValueMax(Value:string);
  208. begin
  209.   if FValueMax<>Value then FValueMax:=Value;
  210. //  FChekValueMax:=False;
  211. Changed(False);
  212. end;
  213.  
  214. procedure TxMiColumn.SetCheckValueMax(Value: Boolean);
  215. begin
  216.   if  FChekValueMax<>Value then  FChekValueMax:=Value;
  217. //  MixChange(true);
  218. //  TDBGrid(TDBGridPruebas).Invalidate;
  219. Changed(False);
  220. end;
  221. //***********************MID
  222. procedure TxMiColumn.SetColorValueMid(Value: TColor);
  223. begin
  224.     if FCcolorValueMid<>Value then FCcolorValueMid:=Value;
  225. //    FChekValueMid:=False;
  226. Changed(False);
  227. end;
  228.  
  229. procedure TxMiColumn.SetCheckValueMid(Value: Boolean);
  230. begin
  231.   if  FChekValueMid<>Value then  FChekValueMid:=Value;
  232. //  TDBGrid(TDBGridPruebas).Invalidate;
  233. Changed(False);
  234. end;
  235. procedure TxMiColumn.SetCheckValueType(Value: Boolean);
  236. begin
  237.   if FCheckValueType<>Value then  FCheckValueType:=Value;
  238.   Changed(False);
  239.  
  240. end;
  241.  
  242. {TMiGridColumns}
  243. function TxMiGridColumns.Add: TxMiColumn;
  244. begin
  245.   Result := TxMiColumn(inherited Add);
  246. end;
  247.  
  248. function TxMiGridColumns.GetColumn(Index: Integer): TxMiColumn;
  249. begin
  250.   Result := TxMiColumn(inherited Items[Index]);
  251. end;
  252.  
  253. procedure TxMiGridColumns.SetColumn(Index: Integer; Value: TxMiColumn);
  254. begin
  255.   Items[Index].Assign(Value);
  256. //  TDBGrid(TxDBGridPruebas).Invalidate;
  257. end;
  258.  
  259. {TDBGridPruebas}
  260. constructor TxDBGridPruebas.Create(AOwner : TComponent);
  261. begin
  262.   inherited Create(AOwner);
  263. end;
  264.  
  265. destructor TxDBGridPruebas.Destroy;
  266. begin
  267.   inherited Destroy;
  268. end;
  269.  
  270. //function TxDBGridPruebas.GetColumns: TxMiGridColumns;
  271. //begin
  272. //  Result := TxMiGridColumns(inherited Columns)
  273. //end;
  274.  
  275. //procedure TxDBGridPruebas.SetColumns(Value: TxMiGridColumns);
  276. //begin
  277. //  TxMiGridColumns(Columns).Assign(Value)
  278. //end;
  279.  
  280. function TxDBGridPruebas.CreateColumns: TDBGridColumns;
  281. begin
  282. //    Result := TDBGridColumns.Create(Self, TxMiColumn);
  283.     Result := TxMiGridColumns.Create(Self, TxMiColumn);
  284. end;
  285.  
  286. procedure TxDBGridPruebas.DrawColumnCell(const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
  287. begin
  288. //      Columns[Column.ID].
  289.  
  290.  
  291.     if Column.Field.DataSet.FieldByName(Self.Columns[Column.ID].FieldName).AsString<>'' then  //Comprobamos qe el campo no este vacio
  292.     BEGIN  //No se si cambioralo por isnull
  293.       if (Columns[Column.ID].FCheckValueType=true) then
  294.       begin
  295.           begin
  296.             if Columns[Column.ID].FChekValueLow=true then
  297.             begin
  298.                 if Column.Field.DataSet.FieldByName(Columns[Column.ID].FieldName).AsInteger <= StrToInt(Columns[Column.ID].FValueLow) then
  299.                     Canvas.Brush.Color:=Columns[Column.ID].ColorValueLow;
  300.                 DefaultDrawColumnCell(rect,DataCol,Column,State);
  301.             end;
  302.             if Columns[Column.ID].CheckValueMax=true then
  303.             begin
  304.                 if Column.Field.DataSet.FieldByName(Columns[Column.ID].FieldName).AsInteger >= StrToInt(Columns[Column.ID].ValueMax) then
  305.                     Canvas.Brush.Color:=Columns[Column.ID].ColorValueMax;
  306.                 DefaultDrawColumnCell(rect,DataCol,Column,State)
  307.             end;
  308.             if Columns[Column.ID].CheckValueMid=true then
  309.             begin
  310.                 if ((Column.Field.DataSet.FieldByName(Columns[Column.ID].FieldName).AsInteger > StrToInt(Columns[Column.ID].ValueLow)) and
  311.                   (Column.Field.DataSet.FieldByName(Columns[Column.ID].FieldName).AsInteger < StrToInt(Columns[Column.ID].ValueMax))) then
  312.                     Canvas.Brush.Color:=Columns[Column.ID].ColorValueMid;
  313.                 DefaultDrawColumnCell(rect,DataCol,Column,State)
  314.             end;
  315.           end;
  316.       end else begin          //Aqui ira para float
  317. //          if (.Columns[Column.ID].FCheckValueType=true) then if (.Columns[Column.ID].FXValueType=ValueFloat) and (Column.Field.DataType = ftFloat) then
  318. //                                                            else if (.Columns[Column.ID].FXValueType=ValueFloat) then
  319.         begin
  320.           if Columns[Column.ID].ChekValueLow=true then
  321.           begin
  322.               if Column.Field.DataSet.FieldByName(Columns[Column.ID].FieldName).AsFloat <= StrToFloat(Columns[Column.ID].ValueLow) then
  323.                   Canvas.Brush.Color:=Columns[Column.ID].ColorValueLow;
  324.               DefaultDrawColumnCell(rect,DataCol,Column,State);
  325.           end;
  326.           if Columns[Column.ID].CheckValueMax=true then
  327.           begin
  328.               if Column.Field.DataSet.FieldByName(Columns[Column.ID].FieldName).AsFloat >= StrToFloat(Columns[Column.ID].ValueMax) then
  329.                   Canvas.Brush.Color:=Columns[Column.ID].ColorValueMax;
  330.               DefaultDrawColumnCell(rect,DataCol,Column,State)
  331.           end;
  332.           if Columns[Column.ID].CheckValueMid=true then
  333.           begin
  334.               if ((Column.Field.DataSet.FieldByName(Columns[Column.ID].FieldName).AsFloat > StrToFloat(Columns[Column.ID].ValueLow)) and
  335.                 (Column.Field.DataSet.FieldByName(Columns[Column.ID].FieldName).AsFloat < StrToFloat(Columns[Column.ID].ValueMax))) then
  336.                   Canvas.Brush.Color:=Columns[Column.ID].ColorValueMid;
  337.               DefaultDrawColumnCell(rect,DataCol,Column,State)
  338.           end;
  339.         end;
  340.       end;
  341.     END;
  342. end;
  343. end.



No puedo ejecutar ya que todas las propiedades nuevas no las encuentra y si añado la propiedad columns, con sus metodos de lectura y grabacion, compila pero persiste el error

List index out bounds (x)  Donde X es un número




  • 0




IP.Board spam blocked by CleanTalk.