none
Formularios que heredan diseño de forma dinámica. RRS feed

  • Pregunta

  • Buenas tardes a todos.

    Lo que necesito hacer básicamente es tener un formulario que podrá cambiar su diseño según la librería que se le diga por configuración (¿LoadAssembly quizás?).

    Con herencia no lo veo posible ya que ésta sólo permite heredar de una sola clase, y si utilizo la herencia a multinivel tendría que estar recompilando la aplicación principal cada vez que me vea en la necesidad de agregar una nueva librería.

    El escenario:

    • Librería que contiene diseño de formulario (pueden ser varias librerías).
    • La aplicación principal estará en producción y según la configuración especificada en su app.config cargará el ensamble con el diseño del formulario (¿es esto posible y cómo si lo es?).

    Sólo requiero una idea que me ponga en el camino correcto.

    Editado: Quizás la pregunta debería ser así: ¿cómo cargar un diseño de formulario con Assembly.Load y heredarlo a un formulario?

    Gracias de antemano por su ayuda.

    Saludos.




    • Editado SantuarioMan miércoles, 24 de septiembre de 2014 20:32
    miércoles, 24 de septiembre de 2014 20:05

Todas las respuestas

  • Para cargar un formulario cualquiera desde un assembly, basta que cargues en memoria el assembly y por reflexión instancies la clase necesaria (tal como Form1) y llames a su método Show. Esto mostrará el formulario en pantalla. Si no sabes usar System.Reflection, pregunta y trataremos de escribirte el código necesario.

    Eso en principio es simple de hacer con pocas líneas de código. El problema está en el caso de que necesites que ese formulario no solo se muestre en pantalla, sino que además quieras que ejecute código que está definido en la aplicación llamante. En este caso, yo sugeriría usar inyección de dependencias. Básicamente, definirías en una interfaz todos los métodos que deban ser llamados de esta manera, y luego implementarías en una clase del programa principal esos métodos. Después, en todos los formularios que debas cargar desde un assembly, pasarías como parámetro al constructor una variable del tipo de esa interfaz y la salvarías localmente (y evidentemente invocarías a sus métodos en los sitios donde se requiera usar el código común). Lógicamente, al invocar por reflexión el constructor de los assemblies cargados, pasarías como argumento una instancia de la clase en la que implementaste los métodos correspondientes.

    jueves, 25 de septiembre de 2014 8:09
  • Buenas tardes:

    Gracias por tu tiempo en contestar.

    Me parece que no he logrado explicar bien el problema. Lo que necesito hacer básicamente es cargar una librería por Assembly.Load que contiene el diseño que utilizaré en el formulario que lo carga, es decir, sólo requiero heredar la clase que viene del Assembly cargado en la clase que llama al ensamblado, no mostrar un formulario de un ensamblado cargado.

    ¿Es posible hacer esto?

    Nuevamente gracias.

    viernes, 26 de septiembre de 2014 21:35
  • No, sigue sin entenderse lo que quieres hacer. Tal vez deberías poner algún ejemplo.

    La herencia propiamente dicha tiene que resolverse en tiempo de compilación, por lo que no se puede heredar en tiempo de ejecución desde un assembly cargado dinámicamente. Así que lo que quieres conseguir no es axactamente "herencia", sino que deseas simular algunas de las prestaciones que normalmente te daría la herencia.

    Si lo que quieres es aprovechar el aspecto visual de un formulario cargado, entonces necesitas ejecutarlo. Con Winforms, el aspecto visual del formulario viene dado por el código que se compila dentro del InitializeComponent, luego es necesario ejecutar dicha subrutina desde el formulario cargado. Esto puede hacerse por Reflexion sin ningún problema a partir del Assembly cargado dinámicamente.

    Pero después de eso desearás que el formulario haga algo, no te conformarás con que simplemente "se vea". Si lo tuvieses en tiempo de compilación, habrías podido heredar de él y hacer desde la clase hija un override de los métodos del formulario, logrando introducir el código ejecutable desde la clase heredada. Pero con un formulario cargado por reflexión no cabe esta opción, así que tienes que agregarle el código ejecutable por otra vía; no puede ser por herencia. Lo más típico sería inyectar el comportamiento como dependencia a través de una interfaz. O alternativamente, exponer eventos públicos desde ese formulario e implementar manejadores para los mismos en el código que lo carga. O pasarle delegados en lugar de usar eventos. Pero auténtica herencia no se puede usar.

    sábado, 27 de septiembre de 2014 7:46
  • Entiendo, me has dejado claro que no es posible utilizar algo parecido a una herencia dinámica.

    Sin embargo me has señalado el camino que sí debo utilizar, el cual es levantar los ensamblados requeridos que contengan los formularios específicos, y en donde cada formulario tendrá un comportamiento predeterminado.

    Hubiera deseado hacerlo de otra forma, pero al parecer no tengo opción.

    En resumen, utilizaré Reflection para cargar los formularios directamente.

    Gracias por tu atención y tiempo.

    Saludos.



    • Editado SantuarioMan lunes, 29 de septiembre de 2014 21:43
    lunes, 29 de septiembre de 2014 21:39