PDA

Ver la Versión Completa : Componentes con DesignTime y RunTime


LoPiTaL
23-10-2010, 12:11:40
Hola a todos!
Estoy realizando un componente que es contenedor de otros, por lo que puedes añadirle "hijos" y te los muestra en el "FormDesigner" dentro de él.
Hasta aquí perfecto.
El problema me viene cuando una vez me dije: qué rollo tener que ir al "Structure Viewer" para poder seleccionar el componente hijo y poderlo editar, cuando yo querría seleccionarlo en el "FormDesigner" haciendo click sobre él y que automáticamente se me seleccione en el "StructureViewer", y que no se me seleccionase siempre el componente contenedor.
Pues me puse manos a la obra. Vi que tenía que pelearme con ToolsAPI y DesignIntf y vi que necesitaba crearme no uno, sino dos packages: uno de runtime y otro designtime.
Pues bien, me creo los dos paquetes como dicen que se debe hacer: el de runtime con cosas de runtime (esto es, mi componente y todas sus funciones) y el de designtime con el Register de éste y la interacción con el IDE.
Ahora bien, cuando hago click en el componente tengo que recibir la acción con una función que reciba el mensaje del ratón, la cual está definida dentro de la clase de mi componente. Por tanto, esto está en el paquete Runtime. Y ahora, dentro de esta función, quiero interactuar con el IDE mediante la interfaz IDesigner, para poder cambiar de componente seleccionado, que no puedo usarla en el Runtime porque si no, la aplicación no me compila (class not found en IDesigner), por tanto, esto es DesigTime.
¿Cuál es la forma estándar de resolver este conflicto? ¿Cómo separo de manera coherente lo que está en Runtime y lo que está en DesignTime?
¿Cómo llamo yo a las funciones que tengo en el paquete DesignTime de forma fácil desde mi clase que tengo en el paquete Runtime cuando son funciones que, según la teoría de OOP, deberían estar todas dentro de la misma clase y además en la sección private?
Lo único que se me ha ocurrido es:
1) Comprobar que csDesigning está en ComponentStatus
2) Cargar dinámicamente el paquete DesignTime, y llamar a las funciones que están en él.
Me parece bastante enrevesado, poco intuitivo y no cumple para nada el concepto OOP, ya que dependo de funciones externas a mi clase para ejecutar acciones que son de mi clase.
¿Qué me gustaría?
Que las funciones estén incluídas en la clase de mi componente y simplemente tenga que:
1) Comprobar que csDesigning está en ComponentStatus
2) Llamar a la función que quiera realizar en DesignTime.

A mí lo único que se me ocurre es separa en dos clases, una para DesignTime y otra para RunTime, con los problemas de tener código duplicado.

Alguna otra idea?

Espero haberme explicado bien,
Un saludo,
LoPiTaL

maeyanes
25-10-2010, 18:13:03
Hola...

Debes tener algún error en el diseño de tu componente, ya que los componentes contenedores deben permitirte seleccionar los componentes "hijos" directamente tal y como lo hace el TPanel.


Saludos...

LoPiTaL
26-10-2010, 09:11:42
Hola, gracias por responder.
El problema es que lo que contiene no son componentes, no estoy implementando una especie de TFrame, sino que son derivados de TPersistent, están incluídos en una TCollection (por lo que aparecen en el ObjectInspector) y tienen un aspecto visual, por lo que aparecen dibujados (realmente pintados, no contenidos a modo de Componente) en el Canvas del TPanel, por eso no puedo seleccionarlos simplemente clickeando ene el panel.
Mi intención era detectar el click en el MouseClick(), ver que estoy en tiempo de diseño (csDesigning in ComponentState) y hacer algo para seleccionar el TCollectionItem correcto en el IDesigner.

Un saludo,
LoPiTaL