Caso práctico de Windows Phone Silverlight a UWP: Bookstore1Windows Phone Silverlight to UWP case study: Bookstore1

En este tema se presenta un caso práctico de migración de una aplicación para Windows Phone Silverlight muy simple a una aplicación para la Plataforma universal de Windows (UWP) de Windows 10.This topic presents a case study of porting a very simple Windows Phone Silverlight app to a Windows 10 Universal Windows Platform (UWP) app. Con Windows 10, puedes crear un paquete de la aplicación único que los clientes pueden instalar en una amplia variedad de dispositivos, como se verá en este caso práctico.With Windows 10, you can create a single app package that your customers can install onto a wide range of devices, and that's what we'll do in this case study. Consulta Guía de aplicaciones para UWP.See Guide to UWP apps.

La aplicación que portaremos consta de un enlace ListBox enlazado con un modelo de vista.The app we'll port consists of a ListBox bound to a view model. El modelo de vista tiene una lista de libros que muestra el título, el autor y la portada de libro.The view model has a list of books that shows title, author, and book cover. Las imágenes de portada de libro tienen el valor de Acción de compilación establecido en Contenido y de Copiar en el directorio de salida establecido en No copiar.The book cover images have Build Action set to Content and Copy to Output Directory set to Do not copy.

En los temas anteriores de esta sección se describen las diferencias entre las plataformas y se proporcionan detalles y pautas sobre el proceso de migración de diversos aspectos de una aplicación, entre ellos el marcado XAML, el enlace a un modelo de vista y el acceso a los datos.The previous topics in this section describe the differences between the platforms, and they give details and guidance on the porting process for various aspects of an app from XAML markup, through binding to a view model, down to accessing data. El objetivo de un caso práctico consiste en complementar esa orientación mostrando un ejemplo real en la práctica.A case study aims to complement that guidance by showing it in action in a real example. En el caso práctico se supone que has leído las directrices, ya que no se repiten.The case studies assume you've read the guidance, which they do not repeat.

Nota:    Al abrir Bookstore1Universal _ 10 en Visual Studio, si ve el mensaje "se requiere la actualización de Visual Studio", siga los pasos para seleccionar un control de versiones de la plataforma de destino en TargetPlatformVersion.Note   When opening Bookstore1Universal_10 in Visual Studio, if you see the message "Visual Studio update required", then follow the steps for selecting a Target Platform Versioning in TargetPlatformVersion.

DescargasDownloads

Descargar la aplicación Bookstore1WPSL8 para Windows Phone Silverlight.Download the Bookstore1WPSL8 Windows Phone Silverlight app.

Descargue la _ aplicación Bookstore1Universal 10 de Windows 10.Download the Bookstore1Universal_10 Windows 10 app.

La aplicación Windows Phone SilverlightThe Windows Phone Silverlight app

Este es el aspecto de Bookstore1WPSL8 (la aplicación que vamos a portar).Here’s what Bookstore1WPSL8—the app that we're going to port—looks like. Es simplemente un cuadro de lista de libros con desplazamiento vertical debajo del encabezado del nombre de aplicación y título de la página.It's just a vertically-scrolling list box of books beneath the heading of the app's name and page title.

aspecto de booksare1wpsl8

Migración a un proyecto de Windows 10Porting to a Windows 10 project

Es una tarea muy rápida crear un nuevo proyecto en Visual Studio, copiar archivos en él desde Bookstore1WPSL8 e incluir los archivos copiados en el nuevo proyecto.It's a very quick task to create a new project in Visual Studio, copy files over to it from Bookstore1WPSL8, and include the copied files in the new project. Empieza creando un proyecto nuevo de Aplicación vacía (Windows Universal).Start by creating a new Blank Application (Windows Universal) project. Asígnele el nombre Bookstore1Universal _ 10.Name it Bookstore1Universal_10. Estos son los archivos que se copian de Bookstore1WPSL8 a Bookstore1Universal _ 10.These are the files to copy over from Bookstore1WPSL8 to Bookstore1Universal_10.

  • Copie la carpeta que contiene los archivos PNG de la imagen de la portada del libro (la carpeta es \ assets \ CoverImages).Copy the folder containing the book cover image PNG files (the folder is \Assets\CoverImages). Después de copiar la carpeta, en el Explorador de soluciones, asegúrate de que Mostrar todos los archivos esté activado.After copying the folder, in Solution Explorer, make sure Show All Files is toggled on. Haz clic con el botń secundario en la carpeta que has copiado y haz clic en Incluir en el proyecto.Right-click the folder that you copied and click Include In Project. Este comando es lo que conocemos como "incluir" archivos o carpetas en un proyecto.That command is what we mean by "including" files or folders in a project. Cada vez que copies un archivo o carpeta, haz clic en Actualizar en el Explorador de soluciones y luego incluye el archivo o la carpeta en el proyecto.Each time you copy a file or folder, click Refresh in Solution Explorer and then include the file or folder in the project. No es necesario hacer esto para los archivos que reemplaces en el destino.There's no need to do this for files that you're replacing in the destination.
  • Copie la carpeta que contiene el archivo de origen del modelo de vista (la carpeta es \ ViewModel).Copy the folder containing the view model source file (the folder is \ViewModel).
  • Copia MainPage.xaml y reemplaza el archivo en el destino.Copy MainPage.xaml and replace the file in the destination.

Podemos conservar los archivos App.xaml y App.xaml.cs que Visual Studio genera en el proyecto de Windows 10.We can keep the App.xaml, and App.xaml.cs that Visual Studio generated for us in the Windows 10 project.

Edite los archivos de código fuente y de marcado que acaba de copiar y cambie las referencias al espacio de nombres Bookstore1WPSL8 a Bookstore1Universal _ 10.Edit the source code and markup files that you just copied and change any references to the Bookstore1WPSL8 namespace to Bookstore1Universal_10. Una forma rápida de hacerlo es usar la función Reemplazar en archivos.A quick way to do that is to use the Replace In Files feature. En el código imperativo del archivo de origen del modelo de vista, deben realizarse estos cambios de migración:In the imperative code in the view model source file, these porting changes are needed:

  • Cambia System.ComponentModel.DesignerProperties a DesignMode y luego usa el comando Resolver en él.Change System.ComponentModel.DesignerProperties to DesignMode and then use the Resolve command on it. Elimina la propiedad IsInDesignTool y usa IntelliSense para agregar el nombre de propiedad correcto: DesignModeEnabled.Delete the IsInDesignTool property and use IntelliSense to add the correct property name: DesignModeEnabled.
  • Usa el comando Resolver en ImageSource.Use the Resolve command on ImageSource.
  • Usa el comando Resolver en BitmapImage.Use the Resolve command on BitmapImage.
  • Elimina using System.Windows.Media; y using System.Windows.Media.Imaging;.Delete using System.Windows.Media; and using System.Windows.Media.Imaging;.
  • Cambie el valor devuelto por la propiedad Bookstore1Universal _ 10. BookstoreViewModel. appname de "BOOKSTORE1WPSL8" a "Bookstore1Universal".Change the value returned by the Bookstore1Universal_10.BookstoreViewModel.AppName property from "BOOKSTORE1WPSL8" to "BOOKSTORE1UNIVERSAL".

En MainPage.xaml, debes realizar los siguientes cambios de puerto:In MainPage.xaml, these porting changes are needed:

  • Cambia phone:PhoneApplicationPage por Page (no olvides las repeticiones en la sintaxis del elemento de propiedad).Change phone:PhoneApplicationPage to Page (don't forget the occurrences in property element syntax).
  • Elimina las declaraciones de prefijo del espacio de nombres phone y shell.Delete the phone and shell namespace prefix declarations.
  • Cambia "clr-namespace" por "using" en la declaración de prefijo del espacio de nombres restante.Change "clr-namespace" to "using" in the remaining namespace prefix declaration.

Podemos optar por corregir los errores de compilación de marcado de forma muy sencilla si queremos ver los resultados pronto, aunque implique quitar el marcado temporalmente.We can choose to correct markup compilation errors very cheaply if we want to see results soonest, even if that means temporarily removing markup. Vamos a mantener un registro de la deuda que acumulamos al hacerlo.But, let's keep a record of the debt we accrue by doing so. En este caso es este.Here it is in this case.

  1. En el elemento raíz Page de MainPage.xaml, elimina SupportedOrientations="Portrait".In the root Page element in MainPage.xaml, delete SupportedOrientations="Portrait".
  2. En el elemento raíz Page de MainPage.xaml, elimina Orientation="Portrait".In the root Page element in MainPage.xaml, delete Orientation="Portrait".
  3. En el elemento raíz Page de MainPage.xaml, elimina shell:SystemTray.IsVisible="True".In the root Page element in MainPage.xaml, delete shell:SystemTray.IsVisible="True".
  4. En la plantilla de datos BookTemplate, elimina las referencias a los estilos PhoneTextExtraLargeStyle y PhoneTextSubtleStyle de TextBlock.In the BookTemplate data template, delete the references to the PhoneTextExtraLargeStyle and PhoneTextSubtleStyleTextBlock styles.
  5. En el TitlePanelStackPanel, elimina las referencias a los estilos PhoneTextNormalStyle y PhoneTextTitle1Style de TextBlock.In the TitlePanelStackPanel, delete the references to the PhoneTextNormalStyle and PhoneTextTitle1StyleTextBlock styles.

Vamos a trabajar en la interfaz de usuario para la familia de dispositivos móviles primero y después podemos considerar otros factores de forma.Let's work on the UI for the mobile device family first, and we can consider other form factors after that. Ahora puedes compilar y ejecutar la aplicación.You can build and run the app now. Este es su aspecto en el emulador móvil.Here's how it looks on the mobile emulator.

la aplicación para uwp en versión móvil, con los cambios en el código fuente inicial

La vista y el modelo de vista funcionan juntos correctamente y ListBox está funcionando.The view and the view model are working together correctly, and the ListBox is functioning. Necesitamos principalmente corregir el estilo y obtener las imágenes que se mostrarán.We mostly just need to fix the styling and get the images to show up.

Saldar la deuda de elementos y algunos estilos inicialesPaying off the debt items, and some initial styling

De forma predeterminada, se admiten todas las orientaciones.By default, all orientations are supported. No obstante, la aplicación de Windows Phone Silverlight se limita explícitamente a solo vertical, de modo que los elementos de la deuda # 1 y # 2 se pagan en el manifiesto del paquete de la aplicación en el nuevo proyecto y comprobando verticalmente con las orientaciones admitidas.The Windows Phone Silverlight app explicitly constrains itself to portrait-only, though, so debt items #1 and #2 are paid off by going into the app package manifest in the new project and checking Portrait under Supported orientations.

En esta aplicación, # el elemento 3 no es una deuda, ya que la barra de estado (anteriormente denominada bandeja del sistema) se muestra de forma predeterminada.For this app, item #3 is not a debt since the status bar (formerly called the system tray) is shown by default. En el caso de los elementos # 4 y # 5, necesitamos encontrar cuatro estilos de TEXTBLOCK plataforma universal de Windows (UWP) que se correspondan con los Windows Phone estilos de Silverlight que se estaban usando.For items #4 and #5, we need to find four Universal Windows Platform (UWP) TextBlock styles that correspond to the Windows Phone Silverlight styles that we were using. Puedes ejecutar la aplicación Windows Phone Silverlight en el emulador y compararla en paralelo con la ilustración de la sección Texto.You can run the Windows Phone Silverlight app in the emulator and compare it side-by-side with the illustration in the Text section. Si hacemos esto y echamos una mirada a las propiedades de los estilos del sistema de Windows Phone Silverlight, podemos generar esta tabla.From doing that, and from looking at the properties of the Windows Phone Silverlight system styles, we can make this table.

| Clave de estilo de Windows Phone SilverlightWindows Phone Silverlight style key | Clave de estilo de UWPUWP style key | |-------------------------------------|------------------------| | PhoneTextExtraLargeStylePhoneTextExtraLargeStyle | TitleTextBlockStyleTitleTextBlockStyle | | PhoneTextSubtleStylePhoneTextSubtleStyle | SubtitleTextBlockStyleSubtitleTextBlockStyle | | PhoneTextNormalStylePhoneTextNormalStyle | CaptionTextBlockStyleCaptionTextBlockStyle | | PhoneTextTitle1StylePhoneTextTitle1Style | HeaderTextBlockStyleHeaderTextBlockStyle |   Para establecer estos estilos puedes escribirlos en el editor de marcado o usar las herramientas de XAML de Visual Studio y establecerlos sin necesidad de escribir nada.To set those styles, you can just type them into the markup editor or you can use the Visual Studio XAML Tools and set them without typing a thing. Para ello, haz clic con el botón derecho en un objeto TextBlock y luego en Editar estilo > Aplicar recurso.To do that, you right-click a TextBlock and click Edit Style > Apply Resource. Para hacerlo con objetos TextBlock en la plantilla de elemento, haz clic con el botón derecho en ListBox y luego en Editar plantillas adicionales > Editar elementos generados (ItemTemplate).To do that with the TextBlocks in the item template, right click the ListBox and click Edit Additional Templates > Edit Generated Items (ItemTemplate).

Hay un fondo blanco con 80 % de opacidad detrás de los elementos porque el estilo predeterminado del control ListBox establece su fondo en el recurso del sistema ListBoxBackgroundThemeBrush.There is an 80% opaque white background behind the items, because the default style of the ListBox control sets its background to the ListBoxBackgroundThemeBrush system resource. Establece Background="Transparent" en ListBox para borrar este fondo.Set Background="Transparent" on the ListBox to clear that background. Para alinear a la izquierda los TextBlock de la plantilla de elemento, edítalos de nuevo tal como se describe más arriba y establece un Margin de "9.6,0" en ambos TextBlock.To left-align the TextBlocks in the item template, edit it again the same way as described above and set a Margin of "9.6,0" on both TextBlocks.

Después de hacerlo, y debido a los cambios relacionados con los píxeles de visualización, debemos recorrer y multiplicar toda dimensión de tamaño fijo que aún no hayamos modificado (márgenes, ancho, alto, etc.) por 0,8.After that is done, because of changes related to view pixels, we need to go through and multiply any fixed size dimension that we haven’t yet changed (margins, width, height, etc) by 0.8. De este modo, las imágenes deben cambiar de 70 x 70 px a 56 x 56 px, por ejemplo.So, for example, the images should change from 70x70px to 56x56px.

Pero obtengamos esas imágenes que vamos a representar antes de mostrar los resultados de la aplicación de estilos.But, let’s get those images to render before we show the results of our styling.

Enlazar una imagen a un modelo de vistaBinding an Image to a view model

En Bookstore1WPSL8, hicimos lo siguiente:In Bookstore1WPSL8, we did this:

    // this.BookCoverImagePath contains a path of the form "/Assets/CoverImages/one.png".
    return new BitmapImage(new Uri(this.CoverImagePath, UriKind.Relative));

En Bookstore1Universal, usamos el esquema de URI "ms-appx".In Bookstore1Universal, we use the ms-appx URI scheme. Para que podamos mantener el resto del código sin modificar, podemos usar una sobrecarga distinta del constructor System.Uri para poner el esquema de URI ms-appx en un URI base y anexarle el resto de la ruta de acceso.So that we can keep the rest of our code the same, we can use a different overload of the System.Uri constructor to put the ms-appx URI scheme in a base URI and append the rest of the path onto that. Así:Like this:

    // this.BookCoverImagePath contains a path of the form "/Assets/CoverImages/one.png".
    return new BitmapImage(new Uri(new Uri("ms-appx://"), this.CoverImagePath));

Estilos universalesUniversal styling

Ahora solo tenemos que hacer algunos retoques finales de estilo y confirmar que la aplicación se vea bien en factores de forma de escritorio (y otros), así como móviles.Now, we just need to make some final styling tweaks and confirm that the app looks good on desktop (and other) form factors as well as mobile. Los pasos se indican a continuación.The steps are below. Puedes usar los vínculos que aparecen en la parte superior de este tema para descargar los proyectos y ver los resultados de todos los cambios entre este punto y el final del caso práctico.And you can use the links at the top of this topic to download the projects and see the results of all the changes between here and the end of the case study.

  • Para ajustar el espaciado entre los elementos, busca la plantilla de datos BookTemplate en MainPage.xaml y elimina el atributo Margin del elemento raíz Grid.To tighten up the spacing between items, find the BookTemplate data template in MainPage.xaml and delete the Margin attribute from the root Grid.
  • Si quieres dar un poco más de espacio al título de la página, puedes restablecer el margen inferior de -5.6 a 0 en el TextBlock del título de la página.If you want to give the page title a little more breathing room, you can reset the bottom margin of -5.6 to 0 on the page title TextBlock.
  • Ahora debemos establecer el elemento Background de LayoutRoot en el valor predeterminado correcto para que la aplicación tenga una apariencia adecuada cuando se ejecute en todos los dispositivos independientemente de cuál sea el tema.Now, we need to set LayoutRoot's Background to the correct default value so that the app looks appropriate when running on all devices no matter what the theme is. Cámbialo de "Transparent" a "{ThemeResource ApplicationPageBackgroundThemeBrush}".Change it from "Transparent" to "{ThemeResource ApplicationPageBackgroundThemeBrush}".

Con una aplicación más sofisticada, este es el punto en el que usamos la directriz de Migración para factores de forma y experiencia de usuario y realmente aprovechamos el factor de forma de cada uno de los muchos dispositivos en los que la aplicación se puede ejecutar.With a more sophisticated app, this would be the point at which we'd use the guidance in Porting for form factor and user experience and really make optimal use of the form factor of each of the many devices the app can now run on. Pero para esta sencilla aplicación podemos dejarlo aquí y ver el aspecto de la aplicación después de esta última secuencia de operaciones de estilo.But, for this simple app, we can stop here and see how the app looks after that last sequence of styling operations. En realidad tiene el mismo aspecto en dispositivos móviles y de escritorio, aunque el uso del espacio en factores de forma ancha no sea el mejor (investigaremos cómo hacerlo en un caso práctico más adelante).It actually looks the same on mobile and desktop devices, although it's not making best use of space on wide form factors (but we'll investigate how to do that in a later case study).

Consulta Cambios de tema para ver cómo controlar el tema de la aplicación.See Theme changes to see how to control the theme of your app.

la aplicación para windows 10 portada

La aplicación para Windows 10 portada ejecutándose en un dispositivo móvilThe ported Windows 10 app running on a Mobile device

Un ajuste opcional en el cuadro de lista para dispositivos móvilesAn optional adjustment to the list box for Mobile devices

Cuando la aplicación se ejecuta en un dispositivo móvil, el fondo de un cuadro de lista es claro en ambos temas de forma predeterminada.When the app is running on a Mobile device, the background of a list box is light by default in both themes. Puede ser el estilo que prefieras y, si es este, no hay nada más que hacer.That may be the style that you prefer and, if so, then there's nothing more to do. No obstante, los controles están diseñados para que puedas personalizar su apariencia sin que ello influya en el comportamiento.But, controls are designed so that you can customize their look while leaving their behavior unaffected. Por lo tanto, si quieres que el cuadro de lista sea oscuro en el tema oscuro (la apariencia que tenía la aplicación original), sigue estas instrucciones en "Un ajuste opcional".So, if you want the list box to be dark in the dark theme—the way the original app looked—then follow these instructions under "An optional adjustment".

ConclusiónConclusion

En este caso práctico se mostró el proceso de migración de una aplicación muy sencilla (y posiblemente, poco realista).This case study showed the process of porting a very simple app—arguably an unrealistically simple one. Por ejemplo, se puede usar controles de lista para seleccionar o establecer un contexto de navegación; la aplicación navega a una página con más detalles sobre el elemento que se pulsó.For instance, list controls can be used for selection or for establishing a context for navigation; the app navigates to a page with more details about the item that was tapped. Esta aplicación en particular no hace nada con la selección del usuario y no tiene navegación.This particular app does nothing with the user's selection, and it has no navigation. Aun así, el caso práctico sirve para dar los primeros pasos y presentar el proceso de migración, así como demostrar técnicas importantes que se puede usar en aplicaciones para UWP reales.Even so, the case study served to break the ice, to introduce the porting process, and to demonstrate important techniques that you can use in real UWP apps.

El siguiente caso práctico es Bookstore2, en el que vamos a ver cómo mostrar datos agrupados y obtener acceso a ellos.The next case study is Bookstore2, in which we look at accessing and displaying grouped data.