Портирование сложных пользовательских интерфейсов с iOS * на Windows 8*

Скачать статью

Скачать статью Porting Advanced User Interfaces From iOS* To Windows 8* [Eng., PDF 620KB]

Аннотация

В этой статье описывается процесс портирования сложных пользовательских интерфейсов с iOS на Windows 8. В качестве примера мы используем приложение для обработки электронных медицинских карт (EMR).

1 Введение

За последние годы планшеты как новая разновидность мобильных компьютерных платформ быстро вышли за пределы потребительского рынка и активно используются в бизнесе и в корпоративных системах. После выпуска операционной системы Windows 8 мы решили предложить разработчикам несколько кратких руководств, которые помогли бы перенести существующие приложения с других платформ, таких как iOS, на Windows 8, а также начать разработку новых приложений для ультрабуков, планшетов и других устройств с архитектурой Intel под управлением Windows 8. Данная статья также преследует эту цель и описывает расширенные возможности пользовательских интерфейсов.

Для iOS основным языком разработки является Objective-C. Для приложений для магазина Windows можно использовать различные средства и языки разработки, в том числе Visual C#, HTML/JavaScript * и прочее. В этом примере мы используем Visual C#* в качестве языка разработки.

1.1 От Xcode * 4 к Visual Studio * 2012

Аналогично тому, как разработчики приложений для iOS используют пакет средств разработки Xcode под управлением OS X *, разработчики приложений для Магазина Windows используют интегрированную среду разработки Visual Studio 2012. Есть аналог и поддерживающему раскадровку средству проектирования интерфейсов Interface Building, применяемому в Xcode 4 (рис. 1): в состав Visual Studio 2012 входит средство XAML Designer (рис. 2).

Рисунок 1. Interface Builder в Xcode 4

Рисунок 2. XAML Designer в Visual Studio 2012

1.2 Пример проекта

Это одна из статей, в основе которых лежит пример проекта. В проекте (ссылка на папку и другие статьи на основе этого проекта) мы перенесли приложение для управления электронными медицинскими картами с iOS на Windows 8. Вот основные требования к приложению:

  • Отображение списка пациентов
  • Отображение личной и медицинской информации о каждом пациенте: личные данные, оплата счетов, основные физиологические показатели, результаты анализов, снимки и пр.
  • Отображение подробных графиков и изображений при выборе соответствующих элементов

Данная статья посвящена расширенным возможностям пользовательского интерфейса этого проекта.

2 Общие принципы устройства пользовательского интерфейса и навигации

В iOS можно использовать контроллер раздельного представления, чтобы отобразить на экране общее и подробное представления. Для группировки информации по категориям можно использовать табличные представления или вкладки. На рис. 3. показано раздельное представление с общим и подробным табличным представлением. В левой части раздельного представления показан прокручиваемый список пациентов. В правой части — медицинские записи, связанные с пациентом, выбранным в списке. Для отображения категорий медицинских записей в одном представлении мы используем табличное представление. Также можно использовать представление вкладок и отображать на каждой вкладке определенную категорию медицинских записей. На рис. 4 показано создание такого представления с помощью раскадровки Xcode 4.

Рисунок 3. Интерфейс в iOS: контроллер раздельного представления, общее табличное представление и подробное табличное представление

Рисунок 4. Используйте раскадровку Xcode для создания раздельного представления, общего и подробного табличного представлений

В приложении для магазина Windows мы можем получить такой же результат, используя иерархическую систему навигации (рис. 5). На странице первого уровня показано табличное представление с плиткой для каждого пациента (рис. 6). Страница второго уровня содержит сгруппированные элементы — медицинские записи пациента, выбранного на странице первого уровня (рис. 7). Страница третьего уровня содержит сгруппированные данные — определенную категорию медицинских записей, выбранных на странице второго уровня (рис. 8). Также может быть страница четвертого уровня с подробной информацией каждого элемента, например с фактическим изображением рентгеновского снимка, выбранного на странице третьего уровня.

Рисунок 5. Иерархическая система навигации в приложении для магазина Windows.

Рисунок 6. В приложении для магазина Windows в представлении корневого уровня находятся плитки списка пациентов.

Рисунок 7. В приложении для магазина Windows на странице второго уровня отображаются медицинские записи, связанные с выбранным пациентом.

Рисунок 8. В приложении для магазина Windows на странице третьего уровня отображается группа, выбранная на странице второго уровня.

В проектах Visual Studio 2012 страница пользовательского интерфейса определяется в XAML-файле, с которым связан файл кода C# (CS-файл). Поскольку переходы с одной страницы на другую обычно вызваны действиями пользователей, например при нажатии элемента табличного представления, для управления навигацией целесообразно использовать прослушиватели событий. На рис. 9 показана страница первого уровня PatientsListPage, где мы определяем прослушиватель событий ItemsGridView_ItemClick.


<common:LayoutAwarePage

    x:Name="pageRoot"

    x:Class="PRApp.PatientsListPage"

    DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="using:PRApp"

    xmlns:common="using:PRApp.Common"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

mc:Ignorable="d">
…

<GridView

            x:Name="itemGridView"

            AutomationProperties.AutomationId="ItemsGridView"

            AutomationProperties.Name="Items"

            TabIndex="1"

            Grid.RowSpan="2"

            Padding="116,136,116,46"

            ItemsSource="{Binding Source={StaticResource itemsViewSource}}"

            ItemTemplate="{StaticResource PatientsItemStyle1}"

            SelectionMode="None"

            IsSwipeEnabled="false" IsItemClickEnabled="True" ItemClick="ItemsGridView_ItemClick"/>    
…

</common:LayoutAwarePage>

Рисунок 9. GridView в XAML-файле PatientsListPage включает прослушиватель событий ItemGsGridView_ItemClick (**)

На рис. 10 показано, что в PatientsListPage.xaml.cs мы реализуем метод ItemsGridView_ItemClick, который вызывает метод Windows Runtime Frame.Navigate() для создания объекта страницы второго уровня PatientGroupItemsPage и отображает ее на экране в качестве текущей страницы. При создании объекта PatientGroupItemsPage мы передаем элемент, получивший щелчок, то есть объект PatientsViewModel.


namespace PRApp

{

    /// <summary>

    /// A page that displays a collection of item previews.

	/// In the Split Application this page

    /// is used to display and select one of the available groups.

/// </summary>
    public sealed partial class PatientsListPage :  PRApp.Common.LayoutAwarePage

    {

…

        void ItemsGridView_ItemClick(object sender, ItemClickEventArgs e)

        {

            this.Frame.Navigate(typeof(PatientGroupItemsPage), ((PatientsViewModel)e.ClickedItem));

        }

…

    }

}

Рисунок 10. В PatientsListPage.cs реализован прослушиватель событий ItemsGridView_ItemClick (**)

В методе LoadState method в PatientGroupItemsPage.xaml.cs (рис. 11) мы получаем объект пациента из этого параметра и создаем коллекцию Groups для модели данных табличного представления.


/// <summary>
/// Populates the page with content passed during navigation. Any saved state is also
/// provided when recreating a page from a prior session.
/// </summary>
/// <param Title="navigationParameter">The parameter value passed to
/// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested.
/// </param>
/// <param Title="pageState">A dictionary of state preserved by this page during an earlier
/// session. This will be null the first time a page is visited.</param>
protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{

    // TODO: Assign a collection of bindable groups to this.DefaultViewModel["Groups"]
    PatientsViewModel patient = (PatientsViewModel)navigationParameter;

    this.DefaultViewModel["Groups"] = pgipvm.GetGroups(_patient.id);

}

Рисунок 11. Метод LoadState в PatientGroupItemsPage.xaml.cs

3 Шаблоны проектов Windows и привязка данных

На рис. 7 и 8 элементы сгруппированы и показаны в удобных табличных представлениях. Шаблоны проектов приложений для магазина Windows в Visual Studio 2012 обеспечивают удобную основу для создания таких страниц пользовательского интерфейса. Готовые шаблоны проектов включают страницу сгруппированных элементов, страницу сведений о группе, страницу сведений об элементе и т. п. В качестве примера мы используем страницу сведений о группе рентгеновских снимков.

В окне обозревателя решений Visual Studio 2012 щелкните имя проекта правой кнопкой мыши и выберите в раскрывающемся меню «Добавить» -> «Создать элемент…». Выберите «Visual C#» в области слева. В середине отображается список готовых шаблонов страниц. Среди этих шаблонов выберите Group Item Page. Область справа предназначена для предварительного просмотра выбранного шаблона. Нужно ввести имя страницы в текстовом поле в нижней части окна (рис. 12) и нажать кнопку «Добавить». Visual Studio 2012 создаст в проекте файлы XRayImagesGroupDetailPage.xaml и XRayImagesGroupDetailPage.xaml.cs.

Рисунок 12. Диалоговое окно добавления нового элемента с шаблонами проектов приложений для магазина Windows (**).

Если изучить созданный файл XRayImagesGroupDetailPage.xaml, мы увидим, что эта страница привязана к контексту данных DefaultViewModel, а элементы табличного представления на этой странице привязаны к Items как к источнику представления коллекции (рис. 13).


<common:LayoutAwarePage

    x:Name="pageRoot"

    x:Class="PRApp.XRayImagesGroupDetailPage"

    DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="using:PRApp"

    xmlns:common="using:PRApp.Common"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d">

 <Page.Resources>
        <!-- Collection of items displayed by this page -->

        <CollectionViewSource

            x:Name="itemsViewSource"

            Source="{Binding Items}"/>

    </Page.Resources>

…

Рисунок 13. В файле XRayImagesGroupDetailPage.xaml указывается исходный объект привязки данных (**)

В XRayImagesGroupDetailPage.xaml.cs мы видим, что XRayImagesGroupDetailPage происходит от PRApp.Common.LayoutAwarePage (рис. 14).


namespace PRApp
{
/// <summary>
/// A page that displays an overview of a single group, including a preview of the items
/// within the group.
/// </summary>
public sealed partial class XRayImagesGroupDetailPage : PRApp.Common.LayoutAwarePage
{…

Рисунок 14. XRayImagesGroupDetailPage происходит от LayoutAwarePage

Если в Visual Studio 2012 развернуть папку Common внутри проекта (рис. 15), то мы увидим, что в ней создана группа файлов. Среди этих файлов LayoutAwarePage.cs будет содержать класс, производный от XRayImagesGroupDetailPage.

Рисунок 15. Папка Common в проекте.

Папка Common также содержит файл BindableBase.cs. Модель данных для представления образуется от этого класса. На рис. 16 приводится класс XRayImagesGroupDetailPageViewModel.


…
namespace PRApp.ViewModels

{

    public abstract class XRayImageDataCommon : BindableBase

    {

    }
    public class XRayImageDataItem : XRayImageDataCommon

    {

    }
    public class XRayImageDataGroup : XRayImageDataCommon

{

…

        private ObservableCollection<XRayImageDataItem> _items = new ObservableCollection<XRayImageDataItem>();

        public ObservableCollection<XRayImageDataItem> Items

        {

            get { return this._items; }

        }

    …
    }
    public sealed class XRayImagesGroupDetailPageViewModel

    {

        …

        public static XRayImageDataGroup GetGroup(string uniqueId)

        {

            …

        }

        …

    }
}

…

Рисунок 16. XRayImagesGroupDetailPageViewModel.cs: классы группы и элементов, производные от класса BindableBase (**)

Для соединения представления с источниками данных мы в методе LoadState класса XRayImagesGroupDetailPage.xaml передаем производный объект группы и элементов контексту DefaultViewModel (рис. 17).


…

        /// <summary>

        /// Populates the page with content passed during navigation.  Any saved state is also

        /// provided when recreating a page from a prior session.

        /// </summary>

        /// <param name="navigationParameter">The parameter value passed to

        /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested.

        /// </param>

        /// <param name="pageState">A dictionary of state preserved by this page during an earlier

        /// session.  This will be null the first time a page is visited.</param>

        protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)

        {

            // TODO: Assign a bindable group to this.DefaultViewModel["Group"]

            // TODO: Assign a collection of bindable items to this.DefaultViewModel["Items"]

            var group = XRayImagesGroupDetailPageViewModel.GetGroup((String) navigationParameter);

            this.DefaultViewModel["Group"] = group;

            this.DefaultViewModel["Items"] = group.Items;

        }

…

Рисунок 17. В файле XRayImagesGroupDetailPage.cs элементы представления связаны с источником данных в методе LoadState (**)

4 Итоги

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

Об авторе

Мяо Вей (Miao Wei) работает инженером по программному обеспечению в отделе корпорации Intel по разработке ПО и обслуживанию. В настоящее время он работает в области масштабирования и внедрения процессоров Intel Atom™. Он обладает более чем 15-летним опытом разработки мобильных платформ. веб-браузеров, приложений и услуг в области геопозицирования, баз данных цифровых карт и других программных продуктов.

*Другие наименования и торговые марки могут быть собственностью третьих лиц.

© Intel Corporation, 2012. Все права защищены.

OpenGL является охраняемым товарным знаком, а OpenGL ES является товарным знаком корпорации Silicon Graphics Inc. Товарные знаки используются с разрешения Khronos.

Pour de plus amples informations sur les optimisations de compilation, consultez notre Avertissement concernant les optimisations.