PDA

Ver la Versión Completa : DBAware en tiempo de ejecución


Chandra
08-07-2007, 15:30:49
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" (http://img296.imageshack.us/img296/2738/imagen140uo5.png); 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 (http://www.clubdelphi.com/foros/showthread.php?t=43661&highlight=WriteComponent). Muestra cómo puedes guardar un form completo, incluyendo todos los componentes que tenga dentro de la forma:


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
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)

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.

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 :(.

En cuanto al diseño, junto con los ejemplos del componente que comentas hay una demo de lo que podría ser un "FormDesigner" (http://img296.imageshack.us/img296/2738/imagen140uo5.png); 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 :)

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 ;)