January 17, 2014 11:29 am

Cómo estar en dos lugares al mismo tiempo con ventanas múltiples

Windows 8.1 habilita poderosas capacidades multitarea al permitir al usuario dividir su pantalla para ver diferentes aplicaciones de la Tienda Windows de manera simultánea. Hay ocasiones sin embargo, cuando es importante tener diferentes ventanas de la misma aplicación en la pantalla. Por ejemplo, cuando se desarrollan sitios web es conveniente tener ventanas de navegador codo con codo para un editor de código, un programa de depuración, y documentación.

Windows 8.1 permite a una sola aplicación mostrar más de una ventana para que los usuarios puedan acceder de manera rápida a dos partes diferentes de la aplicación al mismo tiempo. Esto habilita nuevos escenarios como poder comparar múltiples documentos de manera simultánea o componer un documento mientras se hace referencia a otros materiales desde la misma aplicación. Las aplicaciones pueden aprovechar las múltiples pantallas al mostrar contenido en una y algo diferente en otra. Como desarrolladores, pueden hacer que surja esta capacidad en su aplicación para hacer sus aplicaciones más poderosas y eficientes.

Two windows of Internet Explorer on the screen

Dos ventanas de Internet Explorer en la pantalla (izquierda a derecha: Internet Explorer, Bing Sports, Internet Explorer)

Diseñar una gran experiencia con múltiples ventanas

Si su aplicación cuenta con funciones independientes múltiples, como ver dos piezas de contenido que no se relacionan, pueden ayudar a sus usuarios a ser más productivos al permitir cada función en una ventana separada. El usuario puede entonces mover, ajustar tamaño, mostrar o esconder cada ventana junto con otras aplicaciones para completar de manera sencilla su flujo de trabajo. Si el usuario tiene más de una pantalla unida a su dispositivo, la ventana puede ser movida a cualquiera de esas pantallas.

Correo, Internet Explorer y Lector, son algunas de las primeras aplicaciones con soporte para ventanas múltiples. Correo es un gran ejemplo de cómo deberían trabajar las ventanas múltiples. Comienza con ofrecer una experiencia elegante y eficiente en una sola ventana. Por defecto, cada vez que el usuario comienza a escribir un nuevo mensaje o abre un mail existente, la aplicación muestra ese elemento en la misma ventana de la bandeja de entrada. Ese comportamiento hace que la navegación dentro de la aplicación sea rápida y mantiene simple la administración de ventanas ya que sólo hay una. Sin embargo, los usuarios podrían querer regresar a un mensaje en particular que hayan comenzado a escribir o leer.

Correo da más posibilidades a los usuarios al permitirles abrir de manera opcional un mensaje en especial en una ventana secundaria. Esta nueva ventana de Correo se comporta como una aplicación aparte – el usuario puede colocar la ventana principal de Correo en la pantalla junto al mensaje sin perder de vista ese otro mail importante. Del mismo modo, las superficies de cambio en el sistema, como Alt + Tab y la lista de las aplicaciones usadas de manera reciente, facilitan regresar a este mensaje cuando se abandona la pantalla.

An e-mail message being displayed in a separate window of the Mail app

Mensaje de email proyectado en una ventana separada de la aplicación Correo

Cuando un mensaje se abre en una nueva ventana, la ventana contiene toda la funcionalidad necesaria para actuar en el mensaje. Si el usuario necesita más espacio para leer o escribir el email o utilizar otra aplicación junto a este, se puede mover la ventana de la bandeja de entrada fuera de la pantalla y aun así podrá ver o contestar el email. Todos los controles necesarios para dar formato, editar y enviar el email, están disponibles en la ventana.

Secondary Mail window displaying a reply with editing controls side by side with the Stocks app.

Ventana secundaria de Correo muestra una respuesta con los controles de edición junto a la aplicación Stocks

Para el usuario es posible cerrar una ventana que contenga un mensaje al arrastrarla desde la parte superior de la pantalla a la parte inferior. La ventana también puede salir de la lista de aplicaciones utilizadas de manera reciente si el usuario navega por otras aplicaciones. Sin embargo, Correo salva el email y permite al usuario navegar de regreso a él desde la bandeja de entrada e incluso recrear la nueva ventana. Del mismo modo, la ventana principal de Correo que contiene la bandeja de entrada también puede ser cerrada o hacer que deje la lista de aplicaciones utilizadas. La aplicación de Correo siempre permite al usuario regresar a la bandeja de entrada desde una ventana secundaria con sólo presionar el botón de ‘regreso’ en la ventana. Al tocar el mosaico de Correo en Inicio siempre hace que aparezca la ventana de la aplicación que se utilizó de manera más reciente, para que el usuario pueda regresar a la bandeja de entrada incluso si no tiene acceso a una ventana de Correo en particular.

El diseño de Correo para ventanas secundarias demuestra diversos principios:

  • Mantener al usuario en control: Depender de una acción explicita del usuario para disparar la creación de una nueva ventana en lugar de abrumar a los usuarios con la creación automática de diferentes ventanas.
  • Construir una gran experiencia de ventana única y mejorarla con ventanas secundarias: Los usuarios deberían ser capaces de conseguir todos los escenarios con los que cuenta su aplicación dentro de su ventana principal única. Agreguen ventanas secundarias sólo para tareas que involucren utilizar dos partes separadas de su aplicación al mismo tiempo.
  • Hacer que las ventanas secundarias sean completas y que tengan un propósito: Una ventana secundaria debería contener alguna tarea que pueda ser completada de manera independiente de cualquier otra ventana.
  • Permitir al usuario regresar a los contenidos de cada ventana: Los usuarios pueden perder acceso a ventanas cuando éstas salen de la lista de aplicaciones usadas de manera reciente. Asegúrense que los datos importantes siempre se preserven y permitan recrear de manera sencilla la ventana separada si es que así lo desea el usuario.

Construir una aplicación con ventanas múltiples

Después de haber identificado los escenarios donde su aplicación permita el uso de ventanas secundarias, pueden construir la funcionalidad en sólo unos pasos. El ejemplo MultipleViews demuestra el uso de la API.

Crear una nueva vista

Comiencen por crear una nueva vista a través del método respectivo de su marco de trabajo.

JavaScript:

var newView = MSApp.createNewView(“ms-appx:///html/secondaryView.html”);

C#:

CoreApplicationView newView = CoreApplication.CreateNewView();

Estas llamadas crean un nuevo hilo y una nueva ventana sobre ese hilo. Este emparejamiento 1:1 del hilo y la ventana es llamado una vista (una nueva vista también es creada cuando su aplicación cumple con la fuente Picker y el objetivo Share se contrae). Muchos objetos que creen, incluyendo todas las UI XAML y los objetos regresados de GetForCurrentView, están amarrados a este hilo y lanzarán excepciones cuando las propiedades o métodos sean invocados de otros hilos. Es probable que necesiten sincronizar el acceso a objetos compartidos entre vistas. Comuníquense entre hilos con postMessage en JavaScript o CoreDispatcher.RunAsync en C#/C++/VB.

La primera vista creada cuando su aplicación arranca (llamada vista principal) es especial. Cuando una aplicación está activada por una contracción como File o Protocol Launch, la ventana de la vista principal se presenta al usuario a menos que ApplicationViewSwitcher.DisableShowingMainViewOnActivation sea llamado durante el proceso de arranque (ApplicationViewSwitcher es la clase principal para administrar el comportamiento de ventanas múltiples; hablaremos de esto más adelante). Todos los eventos de activación (incluso si DisableShowingMainViewOnActivation es llamado) son entregados en el hilo de la vista principal. Si esta ventana de vista se cierra el hilo muere por cualquier otra razón, la aplicación será concluida.

Poblar una nueva ventana

El código JavaScript arriba mencionado carga de manera automática la página especificada dentro de la nueva ventana. Pueden entregar cualquier estado extra necesario para instalar esa ventana (por ejemplo el nombre del documento a cargar) con postMessage. Deben dar un paso extra en C#/C++/VB para poblar la ventana.

JavaScript:

newView.postMessage({ myState: ‘My important state’}, thisOrigin);

C#:

await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>

{

var frame = new Frame();

frame.Navigate(typeof(SecondaryViewPage), null);

Window.Current.Content = frame;

});

En el código C#, noten la llamada a RunAsync. Debido a que la función lambda interactúa con la nueva ventana de UI, debe ser llamada en ese hilo de vista.

Mostrar la nueva ventana

Después de que se haya creado una nueva vista, muestren la nueva ventana con ApplicationViewSwitcher.TryShowAsStandaloneAsync. Todas las API ApplicationViewSwitcher aceptan ID de vista, que son enteros que identifican de manera única cada una de las vistas de su aplicación. Recuperen la ID de vista con ApplicationView.Id o ApplicationView.GetApplicationViewIdForWindows. Adicional a esto, el objeto regresado de MSApp.createNewView también tiene una propiedad de ID de vista que contiene la nueva ID de vista. El código completo para crear y mostrar una nueva ventana es el siguiente:

Javascript:

var newView = MSApp.createNewView(“ms-appx:///html/secondaryView.html”);

newView.postMessage({ myState: ‘My important state’ }, thisOrigin);

Windows.UI.ViewManagement.ApplicationViewSwitcher.tryShowAsStandaloneAsync(newView.viewId).done(function (viewShown) {

});

C#:

var newView = CoreApplication.CreateNewView();

int newViewId = 0;

await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>

{

var frame = new Frame();

frame.Navigate(typeof(SecondaryViewPage), null);

Window.Current.Content = frame;

newViewId = ApplicationView.GetForCurrentView().Id;

});

bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);

Notarán que el resultado de TryShowAsStandloneAsync es un Booleano, que indica si la vista especificada fue en verdad presentada al usuario. Su aplicación deberá mostrar una nueva ventana sólo bajo ciertas circunstancias, en particular aquellas donde la ventana de hilo llamada tenga coco en el teclado. Adicional a esto, esta API se comporta igual si una ventana se ha presentado al usuario o no. Así que, cuando los usuarios invoquen “Abrir una nueva ventana” en un elemento que ya ha sido mostrado en una ventana separada, pueden utilizar esta API para traer esa ventana de nuevo a la pantalla.

Cambiar qué ventana está en pantalla

Su aplicación debería permitir al usuario obtener cualquier contenido en la aplicación desde la ventana actual. Algunas veces eso requerirá que su aplicación cambie qué ventana es presentada al usuario. Por ejemplo, las ventanas secundarias de Correo tienen un botón de regreso que, cuando se oprime, muestra la ventana principal de Correo. ApplicationViewSwitcher.SwitchAsync cumple con este requerimiento. Sólo llámenlo desde el hilo de la venta de la que están cambiando, y pasen el ID de vista de la ventana a la que van a cambiar.

JavaScript:

Windows.UI.ViewManagement.ApplicationViewSwitcher.SwitchAsync(viewIdToShow).done();

C#:

await ApplicationViewSwitcher.SwitchAsync(viewIdToShow);

Noten que esta API se comporta igual ya sea que una ventana haya sido o no mostrada al usuario a través de TryShowAsStandaloneAsync.

Cerrar una ventana sin utilizar

Después de que hayan mostrado una ventana al usuario, esta permanece en la lista de aplicaciones utilizadas de manera reciente hasta que el usuario lance suficientes aplicaciones para que esta salga de la lista. El evento Consolidated es disparado en el hilo de la ventana que fue removida de la lista, al proveer esto la aplicación tiene por lo menos una ventana restante más en la lista. Debido a que cada ventana consume memoria, cerrar la ventana cuando reciban el evento es una buena idea. Sin embargo, no cierran la ventana de la vista principal, pues esto provocará que la aplicación finalice.

JavaScript:

Windows.UI.ViewManagement.ApplicationView.getForCurrentView().addEventListener(“consolidated”, viewConsolidated, false);

function viewConsolidated(e) {

if (!isMainView) {

window.close();

}

}

C#:

ApplicationView.GetForCurrentView().Consolidated += ViewConsolidated;

void ViewConsolidated(ApplicationView sender, ApplicationViewConsolidatedEventArgs e)

{

if (!CoreApplication.GetCurrentView().IsMain)

{

Window.Current.Close();

}

}

Si quieren remover una ventana de la pantalla en nombre del usuario, lo pueden hacer con SwitchAsync. Correo hace esto, por ejemplo, cuando se envía o elimina un mensaje contenido en una ventana secundaria. Es una buena práctica, cuando se cierra una ventana, reemplazarla con otra ventana (por lo general la vista principal de la aplicación) para que el usuario pueda continuar con su trabajo en su aplicación.

JavaScript:

Windows.UI.ViewManagement.ApplicationViewSwitcher.switchAsync(

replacementViewId,

viewIdToClose,

Windows.UI.ViewManagement.ApplicationViewSwitchingOptions.consolidateViews).done();

C#:

await ApplicationViewSwitcher.SwitchAsync(

replacementViewId,

viewIdToClose,

ApplicationViewSwitchingOptions.ConsolidateViews);

Mostrar una ventana en otra pantalla

Su aplicación también debería mostrar una ventana en otra pantalla. Por ejemplo, un juego debería tener la proyección que requiera de atención en la pantalla primaria mientras la acción aparece en una TV o proyector. Un visor de presentaciones debería mostrar una diapositiva en el proyector, mientras que el dispositivo principal proyecta las notas de esa diapositiva. La clase ProjectionManager permite a la aplicación colocar ventanas en más pantallas que solo la primaria, y cuida de habilitar la proyección en esa pantalla. Esta API funciona de manera similar a ApplicationViewSwitcher.

Los pasos para mostrar una ventana en una pantalla secundaria son los mismos a los presentados con anterioridad, con algunas diferencias:

Vean el ejemplo de Projection para más detalles

Para finalizar

Windows 8.1 permite a su aplicación mostrar dos o más partes diferentes de la aplicación al mismo tiempo. Esto puede hacer del uso multi tarea de su aplicación una experiencia sin esfuerzo y eficiente para los usuarios.

Si quieren aprender más, vean estos materiales en MSDN: