Caso práctico de Windows Runtime 8.x a UWP: Bookstore2
Este caso práctico, que se basa en la información que se proporciona en Bookstore1, comienza con una aplicación Universal 8.1 que muestra datos agrupados en un control SemanticZoom. En el modelo de vista, cada instancia de la clase Author representa el grupo de los libros escritos por ese autor y, en SemanticZoom, podemos ver la lista de libros agrupados por autor o podemos alejarnos para ver una lista de saltos de autores. La lista de accesos directos ofrece una navegación mucho más rápida que un desplazamiento por la lista de libros. Recorremos los pasos para migrar la aplicación a una aplicación de Windows 10 Plataforma universal de Windows (UWP).
Nota Al abrir Bookstore2Universal_10 en Visual Studio, si ve el mensaje "Se requiere actualización de Visual Studio", siga los pasos descritos en TargetPlatformVersion.
Descargas
Descargue la aplicación Bookstore2_81 Universal 8.1.
Descargue la aplicación Bookstore2Universal_10 Windows 10.
La aplicación Universal 8.1
Esto es lo que Bookstore2_81, la aplicación que vamos a portar, parece. Se trata de un semanticZoom de desplazamiento horizontal (desplazamiento vertical en Windows Phone) que muestra libros agrupados por autor. Puede alejar la lista de accesos directos y desde allí puede volver a cualquier grupo. Hay dos partes principales de esta aplicación: el modelo de vista que proporciona el origen de datos agrupado y la interfaz de usuario que se enlaza a ese modelo de vista. Como veremos, ambas piezas se pueden migrar fácilmente desde la tecnología WinRT 8.1 a Windows 10.
Bookstore2_81 en Windows, vista ampliada
Bookstore2_81 en Windows, vista alejada
Bookstore2_81 en Windows Phone, vista ampliada
Bookstore2_81 en Windows Phone vista alejada
Migración a un proyecto de Windows 10
La solución Bookstore2_81 es un proyecto de aplicación universal 8.1. El proyecto Bookstore2_81.Windows compila el paquete de la aplicación para Windows 8.1 y el proyecto Bookstore2_81.WindowsPhone compila el paquete de la aplicación para Windows Phone 8.1. Bookstore2_81.Shared es el proyecto que contiene código fuente, archivos de marcado y otros recursos y recursos, que usan ambos proyectos.
Al igual que con el caso práctico anterior, la opción que tomaremos (de las descritas en If you have a Universal 8.1 app) is to port the contents of the Shared project to a Windows 10 that targets the Universal device family.
Empiece por crear un nuevo proyecto aplicación vacía (Windows Universal). Asígne un nombre Bookstore2Universal_10. Estos son los archivos que se van a copiar de Bookstore2_81 a Bookstore2Universal_10.
Desde el proyecto compartido
- Copie la carpeta que contiene los archivos PNG de la imagen de portada del libro (la carpeta es \Assets\CoverImages). Después de copiar la carpeta, en Explorador de soluciones, asegúrese de que Mostrar todos los archivos está activado. Haga clic con el botón derecho en la carpeta que copió y haga clic en Incluir en el proyecto. Ese comando es lo que queremos decir por "incluir" archivos o carpetas en un proyecto. Cada vez que copie un archivo o carpeta, cada copia, haga clic en Actualizar en Explorador de soluciones y, a continuación, incluya el archivo o la carpeta en el proyecto. No es necesario hacerlo para los archivos que va a reemplazar en el destino.
- Copie la carpeta que contiene el archivo de origen del modelo de vista (la carpeta es \ViewModel).
- Copie MainPage.xaml y reemplace el archivo en el destino.
Desde el proyecto de Windows
- Copie BookstoreStyles.xaml. Usaremos este como buen punto de partida porque todas las claves de recursos de este archivo se resolverán en una aplicación de Windows 10; Algunos de ellos en el archivo equivalente de WindowsPhone no lo harán.
- Copie SeZoUC.xaml y SeZoUC.xaml.cs. Comenzaremos con la versión de Windows de esta vista, que es adecuada para ventanas anchas y, después, nos adaptaremos a ventanas más pequeñas y, por lo tanto, dispositivos más pequeños.
Edite el código fuente y los archivos de marcado que acaba de copiar y cambie las referencias al espacio de nombres Bookstore2_81 a Bookstore2Universal_10. Una manera rápida de hacerlo es usar la característica Reemplazar en archivos . No se necesitan cambios de código en el modelo de vista ni en ningún otro código imperativo. Pero, solo para que sea más fácil ver qué versión de la aplicación se está ejecutando, cambie el valor devuelto por la propiedad Bookstore2Universal_10.BookstoreViewModel.AppName de "Bookstore2_81" a "BOOKSTORE2UNIVERSAL_10".
En este momento, puede compilar y ejecutar. Así es como se ve nuestra nueva aplicación para UWP después de haber realizado ningún trabajo aún para migrarla a Windows 10.
La aplicación de Windows 10 con cambios de código fuente iniciales que se ejecutan en un dispositivo de escritorio, vista ampliada
La aplicación de Windows 10 con cambios de código fuente iniciales que se ejecutan en un dispositivo de escritorio, vista alejada
El modelo de vista y las vistas alejadas y alejadas funcionan correctamente, aunque hay problemas que hacen que sea un poco difícil de ver. Un problema es que SemanticZoom no se desplaza. Esto se debe a que, en Windows 10, el estilo predeterminado de gridView hace que se diseñe verticalmente (y las directrices de diseño de Windows 10 recomiendan que la usemos de esa manera en aplicaciones nuevas y porte). Sin embargo, la configuración de desplazamiento horizontal en la plantilla de panel de elementos personalizados que copiamos del proyecto de Bookstore2_81 (que se diseñó para la aplicación 8.1) está en conflicto con la configuración de desplazamiento vertical en el estilo predeterminado de Windows 10 que se aplica como resultado de que se haya migrado a una aplicación de Windows 10. Una segunda cosa es que la aplicación aún no adapta su interfaz de usuario para ofrecer la mejor experiencia en ventanas de diferentes tamaños y en dispositivos pequeños. Y, en tercer lugar, los estilos y pinceles correctos aún no se usan, lo que hace que gran parte del texto sea invisible (incluidos los encabezados de grupo que puede hacer clic para alejar). Por lo tanto, en las tres secciones siguientes (cambios de diseño semanticZoom y GridView, interfaz de usuario adaptable y estilo universal) solucionaremos esos tres problemas.
Cambios de diseño de SemanticZoom y GridView
Los cambios de diseño de Windows 10 en el control SemanticZoom se describen en la sección Cambios de SemanticZoom. No tenemos ningún trabajo que hacer en esta sección en respuesta a esos cambios.
Los cambios en GridView se describen en la sección Cambios de GridView/ListView. Tenemos algunos ajustes muy pequeños para adaptarnos a esos cambios, como se describe a continuación.
- En SeZoUC.xaml, en
ZoomedInItemsPanelTemplate
, establezcaOrientation="Horizontal"
yGroupPadding="0,0,0,20"
. - En SeZoUC.xaml, elimine
ZoomedOutItemsPanelTemplate
y quite elItemsPanel
atributo de la vista alejada.
Y listo.
Interfaz de usuario adaptable
Después de ese cambio, el diseño de la interfaz de usuario que SeZoUC.xaml nos ofrece es excelente para cuando la aplicación se ejecuta en una ventana ancha (que solo es posible en un dispositivo con una pantalla grande). Sin embargo, cuando la ventana de la aplicación es estrecha (lo que sucede en un dispositivo pequeño y también puede ocurrir en un dispositivo grande), la interfaz de usuario que teníamos en la aplicación Windows Phone Store es posiblemente la más adecuada.
Podemos usar la característica Visual State Manager adaptable para lograrlo. Estableceremos propiedades en elementos visuales para que, de forma predeterminada, la interfaz de usuario se establezca en el estado estrecho mediante las plantillas más pequeñas que usamos en la aplicación Windows Phone Store. A continuación, detectaremos cuándo la ventana de la aplicación es más amplia o igual a un tamaño específico (medido en unidades de píxeles efectivos) y, en respuesta, cambiaremos las propiedades de los elementos visuales para que obtengamos un diseño más grande y ancho. Colocaremos esos cambios de propiedad en un estado visual y usaremos un desencadenador adaptable para supervisar continuamente y determinar si se debe aplicar ese estado visual, o no, en función del ancho de la ventana en píxeles efectivos. Estamos desencadenando en el ancho de la ventana en este caso, pero también es posible desencadenar en el alto de la ventana.
Un ancho de ventana mínimo de 548 epx es adecuado para este caso de uso porque es el tamaño del dispositivo más pequeño en el que queremos mostrar el diseño ancho. Los teléfonos suelen ser más pequeños que 548 epx, por lo que en un dispositivo pequeño como el que permaneceríamos en el diseño estrecho predeterminado. En un equipo, la ventana se iniciará de forma predeterminada lo suficientemente ancha como para desencadenar el conmutador al estado ancho. Desde allí, podrá arrastrar la ventana lo suficientemente estrecha como para mostrar dos columnas de los elementos de tamaño 250x250. Un poco más estrecho de lo que y el desencadenador desactivará, se quitará el estado visual ancho y el diseño estrecho predeterminado estará en vigor.
Por lo tanto, ¿qué propiedades necesitamos establecer y cambiar para lograr estos dos diseños diferentes? Hay dos alternativas y cada una implica un enfoque diferente.
- Podemos colocar dos controles SemanticZoom en nuestro marcado. Una sería una copia del marcado que usamos en la aplicación Windows Runtime 8.x (con controles GridView dentro de ella) y contraída de forma predeterminada. La otra sería una copia del marcado que usamos en la aplicación Windows Phone Store (con controles ListView dentro de él) y visible de forma predeterminada. El estado visual cambiaría las propiedades de visibilidad de los dos controles SemanticZoom . Esto requeriría muy poco esfuerzo para lograr, pero esto no, en general, una técnica de alto rendimiento. Por lo tanto, si lo usas, debes generar perfiles de tu aplicación y asegurarte de que sigue cumpliendo tus objetivos de rendimiento.
- Podemos usar un único SemanticZoom que contenga controles ListView. Para lograr nuestros dos diseños, en el estado visual ancho, cambiaríamos las propiedades de los controles ListView, incluidas las plantillas que se aplican a ellos, para hacer que se diseñaran de la misma manera que un Control GridView. Esto podría funcionar mejor, pero hay tantas pequeñas diferencias entre los distintos estilos y plantillas de GridView y ListView y entre sus distintos tipos de elementos que es la solución más difícil de lograr. Esta solución también está estrechamente acoplada a la forma en que los estilos y plantillas predeterminados están diseñados en este momento en el tiempo, lo que nos da una solución frágil y sensible a los cambios futuros en los valores predeterminados.
En este caso práctico, vamos a ir con la primera alternativa. Pero, si te gusta, puedes probar la segunda y ver si eso funciona mejor para ti. Estos son los pasos que se deben seguir para implementar esa primera alternativa.
- En SemanticZoom en el marcado del nuevo proyecto, establezca
x:Name="wideSeZo"
yVisibility="Collapsed"
. - Vuelva al proyecto Bookstore2_81.WindowsPhone y abra SeZoUC.xaml. Copie el marcado del elemento SemanticZoom fuera de ese archivo y péguelo inmediatamente después
wideSeZo
en el nuevo proyecto. Establezcax:Name="narrowSeZo"
en el elemento que acaba de pegar. - Pero
narrowSeZo
necesita un par de estilos que aún no hemos copiado. De nuevo en Bookstore2_81.WindowsPhone, copie los dos estilos (AuthorGroupHeaderContainerStyle
yZoomedOutAuthorItemContainerStyle
) fuera de SeZoUC.xaml y péguelos en BookstoreStyles.xaml en el nuevo proyecto. - Ahora tienes dos elementos SemanticZoom en tu nuevo SeZoUC.xaml. Encapsula esos dos elementos en una cuadrícula.
- En BookstoreStyles.xaml en el nuevo proyecto, anexe la palabra
Wide
a estas tres claves de recursos (y a sus referencias en SeZoUC.xaml, pero solo a las referencias dentrowideSeZo
de ):AuthorGroupHeaderTemplate
,ZoomedOutAuthorTemplate
yBookTemplate
. - En el proyecto Bookstore2_81.WindowsPhone, abra BookstoreStyles.xaml. En este archivo, copie los mismos tres recursos (mencionados anteriormente) y los dos convertidores de elementos de lista de accesos directos, y la declaración de prefijo de espacio de nombres Windows_UI_Xaml_Controls_Primitives, y péguelos todos en BookstoreStyles.xaml en el nuevo proyecto.
- Por último, en SeZoUC.xaml en el nuevo proyecto, agregue el marcado adecuado de Visual State Manager a la cuadrícula que agregó anteriormente.
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="WideState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="548"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="wideSeZo.Visibility" Value="Visible"/>
<Setter Target="narrowSeZo.Visibility" Value="Collapsed"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
...
</Grid>
Estilo universal
Ahora, vamos a solucionar algunos problemas de estilo, incluido uno que se introdujo anteriormente al copiar desde el proyecto anterior.
- En MainPage.xaml, cambie
LayoutRoot
fondo a"{ThemeResource ApplicationPageBackgroundThemeBrush}"
. - En BookstoreStyles.xaml, establezca el valor del recurso
TitlePanelMargin
0
en (o cualquier valor que le resulte bueno). - En SeZoUC.xaml, establezca el margen de
wideSeZo
en0
(o cualquier valor que le resulte bueno). - En BookstoreStyles.xaml, quite el atributo Margin de
AuthorGroupHeaderTemplateWide
. - Quite el atributo FontFamily de
AuthorGroupHeaderTemplate
y deZoomedOutAuthorTemplate
. - Bookstore2_81 usaron las
BookTemplateTitleTextBlockStyle
claves de recurso ,BookTemplateAuthorTextBlockStyle
yPageTitleTextBlockStyle
como un direccionamiento indirecto para que una sola clave tuviera implementaciones diferentes en las dos aplicaciones. Ya no necesitamos ese direccionamiento indirecto; podemos hacer referencia directamente a los estilos del sistema. Por lo tanto, reemplace esas referencias en toda la aplicación porTitleTextBlockStyle
,CaptionTextBlockStyle
yHeaderTextBlockStyle
respectivamente. Puede usar la característica Reemplazar en archivos de Visual Studio para hacerlo de forma rápida y precisa. Después, puede eliminar esos tres recursos no utilizados. - En
AuthorGroupHeaderTemplate
, reemplace porSystemControlBackgroundAccentBrush
PhoneAccentBrush
y establezcaForeground="White"
en TextBlock para que se vea correcto al ejecutarse en la familia de dispositivos móviles. - En
BookTemplateWide
, copie el atributo Foreground del segundo TextBlock en el primero. - En
ZoomedOutAuthorTemplateWide
, cambie la referencia aSubheaderTextBlockStyle
(que ahora es un poco demasiado grande) a una referencia aSubtitleTextBlockStyle
. - La vista alejada (la lista de accesos directos) ya no superpone la vista ampliada en la nueva plataforma, por lo que podemos quitar el
Background
atributo de la vista alejada denarrowSeZo
. - Para que todos los estilos y plantillas estén en un archivo, salga
ZoomedInItemsPanelTemplate
de SeZoUC.xaml y en BookstoreStyles.xaml.
Esa última secuencia de operaciones de estilo deja que la aplicación tenga este aspecto.
La aplicación de Windows 10 portado que se ejecuta en un dispositivo de escritorio, vista ampliada, dos tamaños de ventana
La aplicación de Windows 10 migrada que se ejecuta en un dispositivo de escritorio, vista alejada, dos tamaños de ventana
La aplicación de Windows 10 migrada que se ejecuta en un dispositivo móvil, vista ampliada
La aplicación de Windows 10 migrada que se ejecuta en un dispositivo móvil, vista alejada
Conclusión
Este caso práctico implicaba una interfaz de usuario más ambiciosa que la anterior. Al igual que con el caso práctico anterior, este modelo de vista concreto no requería trabajo en absoluto y nuestros esfuerzos fueron principalmente en la refactorización de la interfaz de usuario. Algunos de los cambios eran el resultado necesario de combinar dos proyectos en uno, a la vez que apoyaban muchos factores de forma (de hecho, muchos más de los que podíamos antes). Algunos de los cambios se han realizado con los cambios realizados en la plataforma.
El siguiente caso práctico es QuizGame, en el que se examina el acceso y la visualización de datos agrupados.