Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   como ordena delphi los fields de un objeto (https://www.clubdelphi.com/foros/showthread.php?t=17939)

oworty 26-01-2005 18:02:09

como ordena delphi los fields de un objeto
 
Hola a todos!

Recientemente he tenido la necesidad de crear un objeto nuevo a partir del ya conocido DBGRID, hasta aqui todo bien, de hecho todo me funciona bien a exception de un pequeño detalle, pero me JODE mucho!!! no se como solucionarlo.

Mi componente en tiempo de diseño tiene ya las columnas y ColumnAutoSize con los valores que deseo para la ejecucion del programa. Mi sorpresa viene cuando ejecuto el programa y se lanza mi metodo SetColumnAutoSize que este pierde el valor que yo tengo en tiempo de diseño, entiendo que pierde el valor porque el metodo impide que se grabe un valor si no existen las columnas. Claro como puedo hacer que delphi cree primero las columnas y nuevo llame a mi metodo? Intente cambiar el nombre de mi propiedad y campo a SizeableColumn y FSizeableColumn para ver si delphi crea los propiedades y los campos ordenados por nombre pero tampoco funciono, No se ya que más hacer.

Gracias a todos por su tiempo.

Código:

 
  TDBGridOrca = class(TDBGrid)
  private
        { Private declarations }
        FColumnAutoSize: Integer;
        procedure SetColumnAutoSize(const Value: Integer);
  published
        { Published declarations }
        property ColumnAutoSize: Integer read FColumnAutoSize
          write SetColumnAutoSize default -1;
  end;
 
procedure TDBGridOrca.SetColumnAutoSize(const Value: Integer);
begin
  if Value = FColumnAutoSize then Exit;
  if Columns.Count = 0 then Exit;
  if Value > (Columns.Count - 1) then
        raise Exception.Create('No existe la columna.');
  FColumnAutoSize := Value;
end;


roman 26-01-2005 18:23:03

No entiendo por qué haces esas verificaciones en el método SetColumnAutoSize. A fin de cuentas el método únicamente asigna un valor pero no hace el redimensionamiento en sí de manera que no afecta si existen o no columnas.

El orden de creación supongo que tiene que ver con el orden en que están declarados pero yo no confiaría en eso ya que puede cambiar el día de mañana.

Por otra parte, aunque no estoy seguro de cómo aplicaría en tu caso ya que no conozco más detalles, es posible que te interese saber del método Loaded. Este método lo llama la VCL cuando ya se han cargado todas las propiedades desde el archivo dfm.

A lo que voy es que, suponiendo que tengas un método ResizeColumns que- éste sí -deba ejecutarse sólo si existen columnas, podrías redefinir (override) el método para ahí llamar a ResizeColumns, teniendo la seguridad de que ya se crearon. De esta forma, quitando las verificaciones que tienes en SetColumnAutoSize, el valor de FColumnAutoSize será el que escojas en tiempo de diseño y el redimensionamiento en sí se efectuará hasta el método Loaded.

// Saludos

oworty 27-01-2005 09:30:58

Antes de nada muchas gracias por tu respuesta.


No he puesto todo el codigo fuente del objeto para no agrandar el mensaje. Necesito poner la verificacion para que si en tiempo de diseño o en tiempo de ejecucion se dice que la columna autoajustable es una que realmente no existe que no deje seguir. Claro el mejor sitio es este en el metodo SetColumnAutoSize para que nunca tome un valor incorrecto.

Segun me ha parecido entender en tu mensaje, me dices que en el SetCoulmnAutoSize no ponga la verificacion y que luego la controle en otro sitio, ese sitio no seria en el ResizeColumns(en mi componente se llama ValidateSizeableColumn) porque el aun no tendria las columnas, y además debería volver a poner mi FColumnAutoSize a -1 y no quiero ir cambiando tanto el field, pretendo que sea todos los valores por el usuario.

Sin embargo no sabia que el metodo Loaded se lanza justo y cuando se carga un componente y este ya ha tomado todos los valores del tiempo de diseño, sabiendo esto puedo, poner aquí la verificacion que me has dicho de si no existen las columnas.

Tal vez otra solucion seria poner un estado o intentar reutilizar el de de tcomponent para ver si el componente se esta cargando y si es asi permitir la escritura de mi campo FColumnAutoSize pese que no tenga las columnas porque estas vendrán luego.

De nuevo gracias por todo y por darme pistar e ideas nuevas, voy a ver si les saco provecho, ya te contare.

Código:

 
procedure TDBGridOrca.SetColumnAutoSize(const Value: Integer);
begin
  if Value = FColumnAutoSize then Exit;
  if Columns.Count = 0 then Exit;
  if Value > (Columns.Count - 1) then
        raise Exception.Create('No existe la columna.');
  FColumnAutoSize := Value;
       
  LayoutChanged;
end;

procedure TDBGridOrca.LayoutChanged;
begin
  inherited;
  ValidateSizeableColumn();
end;


oworty 27-01-2005 15:47:53

Hola a todos

Gracias a todos y en especial a Roman por su ayuda!
Lo consegui, la solución es simple! Adjunto el fragmento de código con la corrección del método de como solucionar el problema y allí explico el porque!

Código:

 
procedure TDBGridOrca.SetColumnAutoSize(const Value: Integer);
begin
  if Value = FColumnAutoSize then Exit;
  // Necesito comprobar el estado del componente. El componente se
  // carga con los valores del tiempo de diseño y estos son correctos, claro,
  // como se esta cargando y no se puede controlar el orden de creacion de los
  // campos asigno directamente los valores sin validarlos.
  if (csLoading in ComponentState) then
        FColumnAutoSize := Value
  else if Value > (Columns.Count - 1) then
        raise Exception.Create('No existe la columna.')
  else
  begin
        FColumnAutoSize := Value;
        LayoutChanged;
  end;
end;



La franja horaria es GMT +2. Ahora son las 09:04:58.

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