Пример переноса со среды выполнения Windows 8.x на UWP: Bookstore2

Этот пример, в котором используются данные из примера Bookstore1, начинается с универсального приложения для версии 8.1, отображающего сгруппированные данные в элементе управления SemanticZoom. В модели представления каждый экземпляр класса Author представляет группу книг одного автора, а в классе SemanticZoom мы можем просмотреть список книг, сгруппированных по автору, или уменьшить представление, чтобы просмотреть список переходов по авторам. Список переходов — это гораздо более быстрый способ навигации, чем прокрутка списка книг. Рассмотрим шаги переноса приложения в приложение Windows 10 универсальной платформы Windows (UWP).

Примечание Если при открытии Bookstore2Universal_10 в Visual Studio отображается сообщение "Требуется обновление Visual Studio", выполните действия, описанные в разделе TargetPlatformVersion.

Файлы для загрузки

Скачайте приложение Bookstore2_81 Universal 8.1.

Скачайте приложение Bookstore2Universal_10 Windows 10.

Универсальное приложение для версии 8.1

Вот как выглядит Bookstore2_81 приложение, которое мы собираемся перенести. В нем используется горизонтальная прокрутка (вертикальная прокрутка в Windows Phone) SemanticZoom и отображаются книги, сгруппированные по автору. Вы можете уменьшить представление и перейти в список переходов, откуда можно вернуться в любую группу. Приложение состоит из двух основных элементов: модели представления, которая дает сгруппированный источник данных, и пользовательского интерфейса, который привязывается к этой модели. Как мы увидим, оба этих элемента легко можно перенести с платформы WinRT 8.1 в Windows 10.

bookstore2-81 в окнах, увеличенное представление

Bookstore2_81 в Windows с увеличенным представлением

bookstore2-81 в окнах, уменьшенное представление

Bookstore2_81 в Windows, уменьшенное представление

bookstore2-81 на Windows Phone, увеличенное представление

Bookstore2_81 Windows Phone, увеличенное представление

bookstore2-81 в Windows Phone, уменьшенное представление

Bookstore2_81 Windows Phone, уменьшенное представление

Перенос в проект Windows 10

Решение Bookstore2_81 — это проект универсального приложения версии 8.1. Проект Bookstore2_81.Windows создает пакет приложения для Windows 8.1, а проект Bookstore2_81.WindowsPhone — пакет приложения для Windows Phone 8.1. Bookstore2_81.Shared — это проект, содержащий исходный код, файлы разметки и другие ресурсы и ресурсы, используемые в обоих других проектах.

Как и в предыдущем примере, мы выберем вариант (из тех, что описаны в разделе Если у вас универсальное приложение для версии 8.1) переноса содержимого общего проекта в Windows 10, которая ориентирована на семейство универсальных устройств.

Начните с создания нового проекта пустого приложения (Windows Universal). Назовите его Bookstore2Universal_10. Это файлы для копирования из Bookstore2_81 в Bookstore2Universal_10.

Из общего проекта

  • Скопируйте папку, содержащую PNG-файлы с изображением обложки книги (папка \Assets\CoverImages). После копирования убедитесь, что в Обозревателе решений включена функция Показать все файлы. Щелкните правой кнопкой мыши на скопированной папке и выберите Включить в проект. Под выполнением этой команды мы и понимаем включение файлов или папок в проект. Каждый раз, копируя файл или папку, нажимайте Обновить в Обозревателе решений, а затем включайте этот файл или папку в проект. Для тех файлов, которые вы заменяете в конечном местоположении, выполнять эту операцию не нужно.
  • Скопируйте папку, содержащую исходный файл модели представления (папка \ViewModel).
  • Скопируйте файл MainPage.xaml и замените на него файл в конечной папке.

Из проекта Windows

  • Скопируйте файл BookstoreStyles.xaml. Мы будем использовать этот файл как отправную точку, так как приложение для Windows 10 сможет обработать все ключи ресурсов из этого файла. Некоторые ключи ресурсов, содержащиеся в аналогичном файле для WindowsPhone, не смогут быть обработаны.
  • Скопируйте файлы SeZoUC.xaml и SeZoUC.xaml.cs. Начнем с версии этого представления для Windows, которая подходит для широких окон, а затем позднее мы сделаем его адаптируемым к небольшим окнам и, следовательно, небольшим устройствам.

Измените исходный код и файлы разметки, которые вы только что скопировали, и измените ссылки на пространство имен Bookstore2_81 на Bookstore2Universal_10. Эту операцию можно быстро выполнить при помощи функции Заменить в файлах. В модель представления или любой другой императивный код вносить изменений не надо. Но чтобы было проще увидеть, какая версия приложения запущена, измените значение, возвращаемое свойством Bookstore2Universal_10.BookstoreViewModel.AppName , с Bookstore2_81 на BOOKSTORE2UNIVERSAL_10.

Сейчас вы можете собрать и запустить приложение. Хотя для его переноса в Windows 10 еще не было выполнено явной работы, вот как выглядит наше новое приложение UWP.

Работа приложения для Windows 10 с начальными изменениями исходного кода на ПК в увеличенном масштабе

Работа приложения для Windows 10 с начальными изменениями исходного кода на ПК в увеличенном масштабе

приложение для Windows 10 с начальными изменениями исходного кода на настольном устройстве, уменьшенное представление

Работа приложения для Windows 10 с начальными изменениями исходного кода на ПК в уменьшенном масштабе

Модель представления, а также увеличенное и уменьшенное представления интегрированы правильно, хотя присутствует некоторые проблемы с отображением. Одна из проблем состоит в том, что SemanticZoom не прокручивается. Причиной этому является то, что в Windows 10 стиль по умолчанию для GridView задает вертикальное использование (и в руководстве по проектированию Windows 10 рекомендуется использовать его таким образом в новых и перенесенных приложениях). Но параметры горизонтальной прокрутки в шаблоне панели настраиваемых элементов, скопированном из проекта Bookstore2_81 (который был разработан для приложения версии 8.1), конфликтуют с параметрами вертикальной прокрутки в стиле windows 10 по умолчанию, который применяется в результате переноса в приложение Windows 10. Вторая причина — это то, что пользовательский интерфейс приложения еще не адаптирован для обеспечения наилучшего взаимодействия в окнах разных размеров и на небольших устройствах. И третья причина состоит в том, что правильные стили и кисти пока не использовались, и большая часть текста невидима (включая заголовки групп, которые можно нажать, чтобы уменьшить масштаб). В следующих трех разделах (Изменения дизайна SemanticZoom и GridView, Адаптивный пользовательский интерфейс и Универсальное оформление) мы исправим эти три проблемы.

Изменения дизайна SemanticZoom и GridView

Изменения дизайна в Windows 10, связанные с элементом SemanticZoom описаны в разделе Изменения SemanticZoom. У нас нет заданий для выполнения в этом разделе в ответ на эти изменения.

Изменения GridView описаны в разделе Изменения элементов проектирования GridView/ListView. Нам нужно сделать незначительные настройки, необходимые для адаптации к этим изменениям, и они описаны ниже.

  • В файле SeZoUC.xaml для ZoomedInItemsPanelTemplate установите значения Orientation="Horizontal" и GroupPadding="0,0,0,20".
  • В файле SeZoUC.xaml удалите ZoomedOutItemsPanelTemplate, а также удалите атрибут ItemsPanel из реализации уменьшенного представления.

Вот и все!

Адаптивный пользовательский интерфейс

После этого изменения макет пользовательского интерфейса, который обеспечивает SeZoUC.xaml, выглядит отлично, когда приложение запущено в широком окне (а это возможно только на устройстве с большим экраном). Но когда окно приложения узкое (это часто случается на небольших устройствах, но может также произойти и на большом устройстве), наиболее подходящим будет интерфейс, который использовался в приложении Магазина Windows Phone.

Для этих целей мы можем использовать адаптивную функцию диспетчера визуальных состояний. Зададим свойства визуальных элементов, так чтобы по умолчанию пользовательский интерфейс помещался в узком состоянии с использованием меньших шаблонов, используемых в приложении Магазина Windows Phone. Затем необходимо определить, когда окно приложения "более широкое" или "эквивалентное" для конкретного размера (измеренного в эффективных пикселях) и изменим свойства визуальных элементов, чтобы получить больший и более широкий макет. Мы внесем эти изменения свойств в визуальное состояние и будем использовать адаптивный триггер для постоянного контроля и определения, следует ли применять это визуальное состояние или нет, в зависимости от ширины окна в эффективные пикселях. В данном случае мы активируем на ширине окна, но можно также активировать на высоте окна.

Минимальная ширина окна в 548 epx подходит для нашего примера, так как это размер самого небольшого устройства, на котором мы хотели бы отображать широкий макет. Размер экрана телефона обычно не превышает 548 epx, поэтому на таком небольшом устройстве, мы можем использовать стандартный узкий макет. На компьютере окно по умолчанию запускается достаточно широким для активации переключения к широкому состоянию. В этом состоянии вы сможете перетащить окно и сделать его достаточно узким для отображения двух столбцов элементов размером 250x250. При размере чуть более узком триггер будет отключен, широкое визуальное состояние будет удалено и стандартный узкий макет будет использоваться.

Итак, какие свойства требуется установить и изменить для использования этих двух различных макетов? Существуют две альтернативы, и каждая использует свой подход.

  1. Мы можем добавить два элемента управления SemanticZoom в нашу разметку. Одна из них будет копией разметки, которую мы использовали в приложении среда выполнения Windows 8.x (с помощью элементов управления GridView внутри нее), и свернута по умолчанию. А другая будет копией разметки, используемой в приложении Магазина Windows Phone (элементы управления ListView используются внутри нее), и она будет по умолчанию видимой. Визуальное состояние будет переключать свойства видимости этих двух элементов управления SemanticZoom. Для этого потребуется совсем немного усилий, но, в целом, это не высокопроизводительный метод. Поэтому, если вы выберете его, выполните профилирование вашего приложения и убедитесь, что оно по-прежнему соответствует целям по производительности.
  2. Или можно использовать SemanticZoom, где будут содержаться оба элемента управления ListView. Для обеспечения возможности использования двух макетов в широком визуальном состоянии нам нужно изменить свойства элементов управления ListView, включая шаблоны, применяемые к ним, чтобы они размещались так же, как размещается GridView. Производительность этого варианта может быть более высокой, но существует так много незначительных различий между разными стилями и шаблонами GridView и ListView, а также между различными типами их элементов, что это решение становится более сложно реализовать. Это решение также тесно связано со способом разработки стандартных стилей и шаблонов, которые используются в данный момент, что приводит к высокой чувствительности такого решения к любым будущим изменениям параметров по умолчанию.

В этом примере мы будем использовать первый вариант. Но при желании вы можете попробовать реализовать второй вариант и проверить, будет ли он более подходящим для вас. Вот какие действия нужно выполнить, чтобы реализовать первый вариант.

  • В SemanticZoom в разметке нового проекта установите значения x:Name="wideSeZo" и Visibility="Collapsed".
  • Назад в проект Bookstore2_81.WindowsPhone и откройте Файл SeZoUC.xaml. Скопируйте разметку элемента SemanticZoom из этого файла и вставьте сразу после wideSeZo в новом проекте. Установите x:Name="narrowSeZo" для элемента, который вы только что вставили.
  • Но для narrowSeZo нужны несколько стилей, которые мы еще не скопировали. Снова в Bookstore2_81.WindowsPhone скопируйте два стиля (AuthorGroupHeaderContainerStyle и ZoomedOutAuthorItemContainerStyle) из Файла SeZoUC.xaml и вставьте их в файл BookstoreStyles.xaml в новом проекте.
  • Теперь у вас есть два элемента SemanticZoom в новом файле SeZoUC.xaml. Заключите эти два элемента в Grid.
  • В файле BookstoreStyles.xaml в новом проекте добавьте слово Wide к этим трем ключам ресурсов (и к ссылкам на них в файле SeZoUC.xaml, но только в ссылкам внутри wideSeZo): AuthorGroupHeaderTemplate, ZoomedOutAuthorTemplate и BookTemplate.
  • В проекте Bookstore2_81.WindowsPhone откройте файл BookstoreStyles.xaml. Из этого файла скопируйте те же три ресурса (упомянутые выше), два конвертера элементов списка переходов и объявление префикса пространства имен Windows_UI_Xaml_Controls_Primitives и вставьте их все в Файл BookstoreStyles.xaml в новом проекте.
  • Наконец, в SeZoUC.xaml в новом проекте добавьте соответствующую разметку диспетчера визуальных состояний в элемент Grid, добавленный ранее.
    <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>

Универсальное оформление

Теперь нужно исправить некоторые проблемы с оформлением, в том числе те, которые мы вызвали ранее, выполняя копирование из старого проекта.

  • В файле MainPage.xaml измените фон LayoutRoot на "{ThemeResource ApplicationPageBackgroundThemeBrush}".
  • В файле BookstoreStyles.xaml установите для источника TitlePanelMargin значение 0 (или другое значение, которое, по вашему мнению, выглядит хорошо).
  • В файле SeZoUC.xaml установите для поля wideSeZo значение 0 (или другое значение, которое, по вашему мнению, выглядит хорошо).
  • В файле BookstoreStyles.xaml удалите атрибут поля из AuthorGroupHeaderTemplateWide.
  • Удалите атрибут FontFamily из AuthorGroupHeaderTemplate и ZoomedOutAuthorTemplate.
  • Bookstore2_81 использовали ключи BookTemplateTitleTextBlockStyleресурсов , BookTemplateAuthorTextBlockStyleи PageTitleTextBlockStyle в качестве косвенного обращения, чтобы один ключ имел разные реализации в двух приложениях. Мы более не нуждаемся в этом методе обхода и можем ссылаться на стили системы напрямую. Замените эти ссылки во всем приложении на TitleTextBlockStyle, CaptionTextBlockStyle и HeaderTextBlockStyle соответственно. Эту операцию можно быстро и точно выполнить при помощи функции Заменить в файлах в Visual Studio. Эти три неиспользуемые ресурса можно удалить.
  • В AuthorGroupHeaderTemplate замените PhoneAccentBrush на SystemControlBackgroundAccentBrush и установите значение Foreground="White" для TextBlock, чтобы обеспечить правильное отображение на семействе мобильных устройств.
  • В BookTemplateWide скопируйте атрибут Foreground из второго TextBlock в первый.
  • В ZoomedOutAuthorTemplateWide замените ссылку на SubheaderTextBlockStyle (который сейчас слишком велик) ссылкой на SubtitleTextBlockStyle.
  • Уменьшенное представление (список переходов) больше не перекрывает увеличенное представление на новой платформе, поэтому мы можем удалить атрибут Background из реализации уменьшенного представления narrowSeZo.
  • Теперь, когда все стили и шаблоны собраны в одном файле, переместите ZoomedInItemsPanelTemplate из файла SeZoUC.xaml в файл BookstoreStyles.xaml.

После описанных выше действий приложение будет выглядеть так.

Перенесенное приложение для Windows 10, запущенное на настольном устройстве, в увеличенном представлении, которое в два раза превышает размеры окна

Перенесенное приложение для Windows 10, запущенное на настольном устройстве, в увеличенном представлении, которое в два раза превышает размеры окна

Перенесенное приложение для Windows 10, запущенное на настольном устройстве, в уменьшенном представлении, которое в два раза превышает размеры окна

Перенесенное приложение для Windows 10, запущенное на настольном устройстве, в уменьшенном представлении, которое в два раза превышает размеры окна

перенесенное приложение для Windows 10, работающее на мобильном устройстве с увеличенным представлением

Перенесенное приложение для Windows 10 запущено на мобильном устройстве в увеличенном представлении

перенесенное приложение для Windows 10, работающее на мобильном устройстве, уменьшенное представление

Перенесенное приложение для Windows 10 запущено на мобильном устройстве в уменьшенном представлении

Заключение

В этом примере представлен более амбициозный пользовательский интерфейс, чем в предыдущем примере. Как и в предыдущем примере, для этой конкретной модели представления не потребовалось выполнять много работы, и все наши усилия были преимущественно потрачены на рефакторинг пользовательского интерфейса. Некоторые изменения потребовались в результате группирования двух проектов и для обеспечения поддержки большого количества форм-факторов (на самом деле намного большего количества, чем когда-либо ранее). И некоторые изменения были связаны с изменениями, которые были применены к платформе.

Следующий пример — QuizGame, где мы рассмотрим доступ к сгруппированным данным и их и отображение.