sábado, septiembre 04, 2010

Una ventana dentro de otra

La Condition Humaine, de René MagritteEste es un truco rápido y sencillo que, sin embargo, es difícil encontrar a la primera buscando en Internet:
  • ¿Cómo meter una ventana dentro de otra?
¿Y para qué le puede hacer falta tal cosa? Un uso evidente sería crear un sistema de docking, que permita agrupar dinámicamente varias ventanas dentro de un contenedor; naturalmente, saber cómo meter una ventana independiente dentro de otro control es sólo el comienzo del proceso.
Pero existe otro uso más mundano: imagine que está creando un administrador de ventanas. Teóricamente, el administrador debe permitirle cambiar el estilo de la aplicación a petición del usuario: de ventanas SDI individuales, a una interfaz basada en pestañas e incluso a un sistema MDI. ¿Cómo deberían implementarse las ventanas para que pudiesen utilizarse con este gestor? Una posibilidad, que he utilizado en varios proyectos, es que las "ventanas" se diseñen como controles de usuarios (UserControl). El motivo es lo fácil que se añade un control dentro de otro, ya sea en tiempo de diseño o de ejecución.
Sin embargo, no es tan evidente cómo meter una instancia de la clase Form dentro de, digamos, un TabPage. Si lo intenta, sin más, provocará una excepción advirtiendo que "no se puede meter un control de nivel superior dentro de otro". El error, por fortuna, nos indica también la solución. Hay una propiedad poco conocida de la clase Form, que hay que poner a false. Por ejemplo, si queremos meter una instancia de la clase Form2 dentro de una nueva página de un TabControl, necesitaremos algo parecido a esto:
var f2 = new Form2();
f2.TopLevel = false;
f2.FormBorderStyle = FormBorderStyle.None;
f2.Dock = DockStyle.Fill;
var tp = new TabPage(
tabControl1.TabPages.Count.ToString());
tabControl1.TabPages.Add(tp);
tp.Controls.Add(f2);
f2.Visible = true;
Aquí he metido la ventana, que puede haber sido diseñada al antojo del programador, dentro de un control de pestañas. Pero es igualmente posible meterla directamente dentro de un prototipo vacío de ventana hija MDI... o lo que se le ocurra.

Etiquetas: , ,

11 Comments:

Anonymous Anónimo said...

Justo lo q necesitaba , muchas gracias, para cuando mas o menos algun curso , libro nuevo?

domingo, septiembre 05, 2010 12:33:00 a. m.  
Blogger Ian Marteens said...

Vaya, pues me alegro. Supongo que lo necesitarás para un "form manager". Estoy investigando también qué hace falta para un sistema de "docking". Pero es mucho más complejo. Para empezar, hay que montar todo el sistema de arrastre de la ventana. Usé, en su momento, los componentes de Weifen Luo, pero siguen teniendo errores a tutiplén, y la arquitectura interna es horrible.

algun curso , libro nuevo

Curso primero (EF); ya están casi completos los ejercicios.

domingo, septiembre 05, 2010 4:34:00 p. m.  
Anonymous Anónimo said...

me alegro por lo del curso ,la vdad estoy usando la suite de Controles Devexpress, supe q la haz usado , q te parece?

domingo, septiembre 05, 2010 11:06:00 p. m.  
Blogger Ian Marteens said...

Pues es muy buena, y la sigo usando... pero la parte que tiene de docking es bastante pobre, para lo que necesito. Yo necesito apilar, sobre todo, formularios "de documentos". Y además, son ventanas SDI.

La verdad es que no entiendo, sabiendo lo que controlan esta gente del asunto, cómo es que no se les ha ocurrido mejorar esa parte del producto. Ahora mismo (domingo noche) estoy experimentando con el tema, y reconozco que no es sencillo. Ya he logrado sustituir el sistema de arrastre de ventanas (tocando tropecientos WM_XXX y guiándome por el código de Weifen).

Si lo simplifico lo suficiente, escribo una entrada: aunque no tenga una aplicación práctica inmediata, hay un par de cosas interesantes sobre cómo Windows Forms maneja estas cosas.

lunes, septiembre 06, 2010 1:04:00 a. m.  
Anonymous Anónimo said...

una consulta q no biene al caso , tienes twitter para q te podamos seguir de cerca?

lunes, septiembre 06, 2010 2:29:00 a. m.  
Anonymous Anónimo said...

y sobre WPF tienes algun consejo?, me parece bueno ami el XALM, y el binding de datos y como se crean los controles , pero lento

lunes, septiembre 06, 2010 3:04:00 a. m.  
Blogger Marco Antonio Santin Torres said...

Que gusto tenerte de vuelva Ian, ya se extrañaban tus comentarios y publicaciones. ¿Para cuando crees que este a la venta el curso?

lunes, septiembre 06, 2010 6:03:00 p. m.  
Blogger Junior said...

Que bueno ver que no se ha perdido la esperanza...

Una pregunta no por lo que digan los de microsoft ¿Ustedes creen que WPF será sustituto de Win Form?

Saludos.

martes, septiembre 07, 2010 4:07:00 p. m.  
Blogger Ian Marteens said...

@Cristian:

tienes twitter

:) No sé ni como funciona. Soy un experto en redes antisociales. Pero le echaré un ojo.

@Cristian y Junior:

y sobre WPF tienes algun consejo?

Es cojonudo. Creo que Alfredo ha estado dándole caña en serio. El problema que le veo sigue siendo la potencia del ordenador. En mi portatil nuevo, un iCore5, va de maravillas, pero en un AMD X2 a 6400, que es una máquina rápida, va a rastras, sobre todo el entorno de Visual Studio 2010... y la tarjeta del AMD es buena: al parecer, depende mucho más del driver concreto que del hardware de la tarjeta. Y del sistema operativo: sobre WinXP, ni hablar. El problema es que el contrato "gordo" que tengo ahora mismo necesita alta velocidad de refrescamiento de datos... sobre una base mayoritaria de máquinas con WinXP.

En pocas palabras, no queda más narices que aprenderlo, pero ahora mismo no me atrevo a cambiar la aplicación que me proporciona las lentejas a WPF.

@Marco:

¿Para cuando crees que este a la venta el curso?

Dos meses. Tengo que organizar la distribución, sobre todo.

Y tengo que escribirte, para que me des los enlaces de tu libro y ponerlos en sitios bien visibles. He estado mirando las estadísticas de búsquedas de este blog, y resulta que hay muchas búsquedas por "Delphi Prism".

miércoles, septiembre 08, 2010 12:15:00 a. m.  
Blogger Unknown said...

Buenas, aunque ha llovido desde la publicación de este post, quería comentar un problema derivado de la técnica de meter un formulario dentro de otro: la función de seleccionar texto con el ratón queda misteriosamente deshabilitada. No encuentro una solución a este problema y navegando por internet, he podido comprobar que otros ya han lidiado con este problema, sin éxito.

Saludos!

jueves, noviembre 18, 2010 10:37:00 a. m.  
Blogger Unknown said...

Debo matizar mi comentario anterior, si establecemos el borde del formulario anidado a FormBorderStyle.None funciona correctamente. No deja de ser curioso e inapropiado el funcionamiento de la técnica en otros casos.

En mi caso particular, estaba intentando aplicar esta técnica para mostrar formularios pseudoModales, es decir, que solo bloqueen la ventana que los llama, y no toda la aplicación. Para conseguirlo, uso algunos trucos sucios que no vienen al caso, entre los cuales se encuentra el meter el formulario pseudoModal dentro del formulario llamante: de este modo me aseguro que siempre se mostrará encima de dicho formulario. Y claro, en este caso si que me interesa disponer del borde del formulario, pero por lo que he podido comprobar, no es posible.

Saludos!

jueves, noviembre 18, 2010 11:19:00 a. m.  

Publicar un comentario

<< Home