Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   DBAware en tiempo de ejecución (https://www.clubdelphi.com/foros/showthread.php?t=45596)

Chandra 08-07-2007 15:30:49

DBAware en tiempo de ejecución
 
Buenas.
Necesito crear una aplicación con una base de datos, con la particularidad de que por cada registro de la DB debe aparecer un interfez distinto. Me explico...

La idea es que la DB contenga productos de un almacén, pero como cada producto tiene sus particularidades, unas vees aparecerán unos campos en un registro y otras no. Lo que yo quiero es que el usuario se confeccione a su medida cada uno de sus registros, arrastrando , soltando y redimensionando componentes dbaware en tiempo de ejecución.

Por ejemplo (un ejemplo ficticio para entendernos, no tomar al pie de la letra), para unos zapatos, el usuario arrastraría a la ficha los siguientes campos dbaware: imágen (ligado al campo blob de la DB), texto de descripción (un dbedit), memo de comentario (dbmemo), texto de talla (un dbedit), etc.


Para insertar un producto de alimentación, arrastraría descripción, comentario, texto con caducidad, etc...

El caso es que en casa registro estuvieran contenidas todas las posibilidades, y el usuario escogiera y confeccionara su propia ficha. Todo esto, claro está, echaría mano de relaciones maestro/detalle.

En fin, y para no enrollarme más, lo que necesito es crear componentes dbaware en tiempo de ejecución y que el usuario pueda redimensionarlos y posicionarlos (ya he visto que Neftalí tiene un componente para eso en su web: TSelectOnRunTime). en una base de datos aparte se guardarían las coordenadas y tamaño de cada componente. Esto se enlazaría con el ID del rgistro de la DB principal.. El caso es que cada vez que se moviera el usuario de un registro a otro (en el evento BeforeScroll, supongo), habría que reconstruir el interface del registro (este tiene imagen, este no, este tiene campo memo, y está situado en tal sitio, este no tiene...). Supongo que tendría que hacer tantas DB como componentes DBaware pueda el usuario poner, y luego, con un SELECT, seleccionar de todas esas DB aquellos registros cuyos IDs correspondan con el de la tabla principal. De esa forma, puede poner 3 memos si le apetece y 5 imágenes en un "registro".

Esta es la idea, pero no tengo muy claro el tema de crear componentes en tiempo de ejecución y redimensionarlos.

Por otra parte, y aquí sí que no tengo ni idea de cómo meterle mano, sería que me gustaría que el usuario pudiera ver las fichas en una especie de conta sin fin, una cinta en la que pudiera hacer scroll. Algo así como un DBCtrlGrid en vertical. El problema del DBCtrlGrid es que no es más que un DBGrid con esteroides, y no puedo poner en cada panel una cosa distinta.

Se me habá ocurrido poner 3 paneles sobre un cuarto panel, hacer scroll, desplazando los 3 sobre el tercero, y que cuando uno se perdiera por debajo, el siguiente registro se dibujara sobre el que debe de aparecer por arriba... un poco lioso, pero es lo único que se me ocurre

También podría hacer scroll con una barra lateral de scroll, pero sin que se viera el efecto óptico del scroll, es decir, que el scroll fuera saltando de registro en registro, pero sin que se moviera verticalmente nada... Pero eso no queda tan estético.

Alguna idea? Por cierto, uso Firebird con DBExpress

Neftali [Germán.Estévez] 09-07-2007 10:31:25

Es una caso atípico, hay que decir.
Bueno, no tengas prisas, piensa bien el diseño, antes de meterte de lleno, porque tal vez luego se torne poco práctico.
Yo tendría en cuenta: Cuantos tipos diferentes de "formularios" va a diseñar el usuario. No es lo mismo si hablamos de 6 o 7, que si estamos hablando del orden de 50.

El tema de recnstruir todo el interface del regitro puede ser muy lento. Haz unas pruebas primero. Una opción (SI HAY POCOS TIPOS DIFERENTES) sería crear un único "formulario" con los diferentes tipos uno en cada capa (estoy pensando en un PageControl con diferentes pestañas o un TNoteBook); La ventaja es que lo crearía al principio y luego dependiendo del tipo de registro, sólo deberías cambiar de pestaña (cosa que sería bastante rápida).
¿Me explico? Esto se convierte en poco viable si tienes muchos tipos diferentes, pero si hay 4 o 5 puede ser una solución muy "ágil".

En cuanto al diseño, junto con los ejemplos del componente que comentas hay una demo de lo que podría ser un "FormDesigner"; No está completo, pero te puede servir de guía para ver cómo se crean diferentes tipo de controles. Hay puedes ver cómo crearlos y redimensionarlos en ejecución.

Para almacernarlos en Base de Datos, tal vez la opción de utilizar Streams sea la más práctica (y más rápida); Revisa LoadComponent y WriteComponent de la clase TStream.

Neftali [Germán.Estévez] 09-07-2007 10:39:28

Además revisa el ejemplo que hay en este hilo. Muestra cómo puedes guardar un form completo, incluyendo todos los componentes que tenga dentro de la forma:

Código:

object Form1: TForm1
  Left = 130
  Top = 56
  Width = 553
  Height = 481
  ActiveControl = Button3
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  Visible = True
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 312
    Top = 40
    Width = 79
    Height = 13
    Caption = 'Esto es un LAbel'
  end
  object Memo1: TMemo
    Left = 0
    Top = 192
    Width = 545
    Height = 262
    Align = alBottom
    ScrollBars = ssBoth
    TabOrder = 0
  end
  object Button1: TButton
    Left = 288
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 1
  end
  object Button2: TButton
    Left = 96
    Top = 8
    Width = 113
    Height = 25
    Caption = 'Button To String'
    TabOrder = 2
    OnClick = Button2Click
  end
  object Button3: TButton
    Left = 96
    Top = 40
    Width = 113
    Height = 25
    Caption = 'Form To String'
    TabOrder = 3
    OnClick = Button3Click
  end
  object Button4: TButton
    Left = 96
    Top = 72
    Width = 113
    Height = 25
    Caption = 'Memo to String'
    TabOrder = 4
    OnClick = Button4Click
  end
  object CheckBox1: TCheckBox
    Left = 288
    Top = 80
    Width = 97
    Height = 17
    Caption = 'CheckBox1'
    TabOrder = 5
  end
end


Chandra 09-07-2007 16:10:39

Cita:

Empezado por Neftali
Cuantos tipos diferentes de "formularios" va a diseñar el usuario. No es lo mismo si hablamos de 6 o 7, que si estamos hablando del orden de 50.

En principio podrían ser tantos como deseara. No habría un límite (lo sé... eso complica aún más las cosas)

Cita:

Empezado por Neftali
El tema de recnstruir todo el interface del regitro puede ser muy lento.

Eso es lo que me preocupa, que al ir de registro en registro, por cada scroll en la tabla, se va a tener que generar un interface distinto.

Cita:

Empezado por Neftali
Haz unas pruebas primero. Una opción (SI HAY POCOS TIPOS DIFERENTES) sería crear un único "formulario" con los diferentes tipos uno en cada capa (estoy pensando en un PageControl con diferentes pestañas o un TNoteBook); La ventaja es que lo crearía al principio y luego dependiendo del tipo de registro, sólo deberías cambiar de pestaña (cosa que sería bastante rápida).
¿Me explico? Esto se convierte en poco viable si tienes muchos tipos diferentes, pero si hay 4 o 5 puede ser una solución muy "ágil".

Pues sí, tienes toda la razón. Eso es lo que había hecho en un primer momento, un PageControl, pero con formularios predefinidos por mi a modo de plantillas a escoger: el usuario escoge una o dos (puede complementar la plantilla de imágenes con la de texto, para incluir algunas notas aclarativas, por ejemplo) y el resto de pestañas, las que no se usan (aquellas que contienen campos vacios dentro del registro) se ocultan. También pensé en un NoteBook, pero es que siempre me han resultado muy incómodos de mover (moverme entre las páginas, digo) en tiempo de diseño ;)).

Lo último que se me había ocurrido era meter marcos (frames) con templates prediseñadas, porque me doy cuenta de que lo de diseñar en tiempo de ejecución me va a traer más de un quebradero de cabeza :(.

Cita:

Empezado por Neftali
En cuanto al diseño, junto con los ejemplos del componente que comentas hay una demo de lo que podría ser un "FormDesigner"; No está completo, pero te puede servir de guía para ver cómo se crean diferentes tipo de controles. Hay puedes ver cómo crearlos y redimensionarlos en ejecución.

Lo miraré, por supuesto :)

Cita:

Empezado por Neftali
Para almacernarlos en Base de Datos, tal vez la opción de utilizar Streams sea la más práctica (y más rápida); Revisa LoadComponent y WriteComponent de la clase TStream.

Estupendo, lo estudiaré.

En cuanto lo otro que comentaba, lo de la cinta sin fin, al final lo he conseguido más o menos. Y he de admitir que me he sorprendido con la apariencia, porque va muy suave el desplazamiento, y eso que no he utilizado técnicas de doble buffer para dibujarla (es como si Delphi 2006 implementara de alguna forma el doble buffer en este tipo de movimientos... raro).

El caso es que utilizo 2 paneles sobre un tercero. una barra de scroll vertival los hace bajar. El panel contenedor tiene el tamaño de uno de los paneles contenidos. Cuando, haciendo scroll, se va a rebasar el segundo panel, este segundo se pone arriba, en el lugar del primero, y se puede seguir haciendo scroll. El resultado es que le dices cuántos paneles va a contener (es decir, cuántos registros tiene la base de datos maestra) y puedes hacer scroll sobre esos dos paneles con apariencia de que hay cientos :D

En fin, voy a seguir investigando. Muchas gracias por tu tiempo y tus ideas ;)


La franja horaria es GMT +2. Ahora son las 06:06:21.

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