domingo, enero 09, 2011

Encontrar Ventana Que Contiene un Control WPF

El post anterior fue sobre como mostrar Ventanas Modales. Ahora para ventanas modales necesitabamos una referencia a Una Ventana para el atributo Owner de nuestro Modal.

Resulta que si nuestra ventana principal (desde la que llamamos al modal)contiene controles de usuario dentro de ella es probable (muy probable que terminemos creando una modal desde un control de usuario . como consecuencia de esto no tendremos la referencia a una ventana para establecer el owner a menos que se la pasemos al contro de usuario al construirlo.

Bueno para encontrar la ventana que contiene nuestro control de usuario ( no solo los nuestros me refiero a cualquier control) tendremos que buscar hacia arriba entre los controles que contienen al nuestro hasta encontrar un objeto que Windows que sirva para nuestro proposito.

Este seria el codigo que sirve para eso:

DependencyObject parent = nuestroControl;

do

{

parent = LogicalTreeHelper.GetParent(parent);

if (parent==null)

{

return null;

}

}

while (parent.GetType().BaseType != typeof(Window));

WindowParent = (parent as Window)



No hay nada del otro mundo aqui. La Clase LogicalTreeHelper Sirve para recorrer el arbol de controles de la aplicacion. (http://msdn.microsoft.com/es-cl/library/system.windows.logicaltreehelper.aspx)
 Esta Linea:

while (parent.GetType().BaseType != typeof(Window));
 
pregunta por el tipo del contro encontrado . Usamos BaseType porque nuestras ventanas heredan de Window asi que GetType() no devuelve Window precisamente (pero si heredan de el)

Ventanas Modales WPF (Windows Presentation Foundation)

Windows Presentation Foundation es una tecnologia creada Por Microsoft, que usa xaml, una forma de xml, para facilitar la creacion de diseños en sus aplicaciones.

Bueno esa seria mi definicion si me preguntaran al respecto.pero podemos preguntarle a Microsoft si deseamos ( a ver si nos convence):

Windows Presentation Foundation (WPF) proporciona a los programadores un modelo de programación unificado con el que generar experiencias de cliente inteligentes de Windows, en las que se incorpora la interfaz de usuario, multimedia y documentos. ( http://msdn.microsoft.com/es-es/library/ms754130.aspx)

El primer problema que encontre con esta tecnologia fue el que da titulo a este post. El clasico caso en el que queremos mostrar un formulario de edicion al hacer click en un registro y necesitamos que sea una ventana modal.

En Windows Form hariamos algo como esto


ventanaModal1.showDialog();

y con esto ya esta todo hecho.

WPF tiene algunos inconveniente pequeño al respecto (o quizas sea alguna novedad que no alcance a comprender).

  1. Si Minimizamos nuestra aplicacion y la volvemos a maximizar luego nuestra ventana se pierde de la vista de nuestra aplicacion ( pero no podremos controlar la aplicacion hasta que cerremos esa ventana)
  2. Nuestra Ventana Se encuentra por defecto como una opcion en la barra de tareas ( lo cual me parece molestoso)

Bien al grano entonces . Si queremos una ventana modal tal y como nos la daria Windows Forms tendremos que agregar 2 lineas a nuestro codigo:

  1. ventanaModal1.ShowInTaskbar = false; // para que no aparezca en la barra de tareas
  2. VentanaModal1.Owner = WindowParent // WindowParent tiene que ser un objeto del tipo Window que sera el que controlara la ventana 
Nuestro codigo quedaria asi:

ventanaModal1.ShowInTaskbar
VentanaModal1.Owner
ventanaModal1.showDialog();

Espero ayudar a aliviar el sufrimiento a algun programador novato

sábado, abril 17, 2010

Layouts en Codeigniter

En un layout generalmente se coloca todo aquello que es común a todas las paginas de nuestro sitio web (cabeceras, pies de pagina, menú principal,etc). Codeigniter no soporta layouts, esto significa que si en determinada etapa de un proyecto nos vemos obligados a cambiar el diseño de nuestro sitio tendremos que modificar todas nuestras vistas una por una. Algunos programadores solucionan este inconveniente por medio de ganchos (hooks en ingles).pero esto tiene el inconveniente de tener que habilitar los ganchos en cada proyecto que realizamos. Mi solucion para agregar layouts a Codeigniter consiste en extender la clase CI_Loader de codeigniter.para una mejor idea cuando al final de un controlador hacemos :

$this->load->view($mi_vista,$data);

estamos llamando al metodo view de la clase CI_Loader de Codeigniter. Ahora para extender una clase de Codeigniter debemos crear un archivo prefijado con  MY_ en la carpeta application/libraries, en nuestro caso el archivo sera MY_Loader.php El codigo es muy simple en verdad:

class MY_Loader extends CI_Loader
{   
function view($view, $vars = array(), $return = FALSE)
{     
$this->content = parent::view($view,$vars,TRUE);   
 parent::view('layout', $vars, $return);  
 }
 function content()   
{     
echo $this->content;   
}
}

La funcion view es la que re definimos en nuestra clase en ella inicialmente llamamos a la funcion view original pero pasando como tercer parámetro TRUE con esto hacemos que la salida no se imprima en pantalla , si no la capturamos en la variable $this->content  luego llamamos a la vista 'layout'( este es el nombre que, muy creativo yo, he dado a mi layout.) pero esta ves si permitimos que se imprima.
La función content permitirá escribir el contenido generado en el lugar de la pagina que nosotros deseamos
Evidentemente habra que crear un archivo llamado 'layout' en la carpeta views de nuestro proyecto.
Un ejemplo de este archivo seria el siguiente.

<html>
<head>
<title>Layout in Codeigniter</title>
</head>
<body> <?php $this->load->content()?> </body>
</html>

Y en nuestro controlador ya podemos seguir trabajando como siempre (es cierto ...no hay que modificar nada).Solo nos queda eliminar en nuestras vistas los menús,pies de pagina y todo aquello que siempre repetíamos.