Простое приложение WinRT

121

Пользовательский интерфейс Windows 8 реализует новую парадигму проектирования, которая с большой вероятностью будет отражена в приложениях Windows Store. Эта парадигма, отчасти вдохновленная городскими вывесками, ставит на первое место содержание, а не программный «хром»; для нее характерно использование простых шрифтов, четкого и открытого стиля оформления, интерфейса на базе плиток и переходных анимаций.

Многие разработчики познакомились с парадигмой проектирования Windows 8 в системе Windows Phone 7; интересно проследить за тем, как изменялось отношение Microsoft к большим и малым компьютерам. За прошедшие годы компания пыталась приспособить архитектуру традиционных настольных приложений Windows к малым устройствам - мобильным компьютерам и телефонам. Теперь дизайн пользовательского интерфейса телефона проникает на планшеты и настольные системы.

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

Windows Phone 8 является конкурентом для популярных мобильных операционных систем, таких как Android и iOS. Для разработки бесплатных программ на айпад и айфон используются совершенно другие языки программирования и платформы (Java для Android и Objective-C для iOS). В настоящее время для приложений Windows 8 существуют три основных варианта программирования, каждый из которых основан на определенном языке программирования и языке разметки:

В этой и последующих статьях мы будем использовать второй вариант. Давайте создадим простой пример, чтобы продемонстрировать возможности WinRT. Предполагается, что на вашем компьютере установлена система Windows 8 или Windows 8.1, а также новейшая версия Microsoft Visual Studio, поддерживающая создание приложений Windows 8. Запустите Visual Studio со стартового экрана Windows 8. Пора браться за программирование!

Первый проект

На исходном экране Visual Studio выберите команду New Project в меню File. Когда на экране появится диалоговое окно New Project, выберите слева категорию Templates, затем подкатегорию Visual C# и строку проекта Windows Store. В списке доступных шаблонов в центральной области выберите тип пустого приложения (Blank App). В нижней части диалогового окна введите в поле Name имя проекта - например, WinRTTestApp. Оставьте в поле Solution Name то же имя решения. При помощи кнопки Browse выберите каталог для программы и щелкните на кнопке ОК. (Говоря об операциях с Visual Studio, я будут использовать «мышиную» терминологию - «щелкнуть» и т.д, но когда речь пойдет о приложениях, которые вы будете создавать, я перейду на терминологию сенсорных экранов - «коснуться» и т.д. Вероятно, версия Visual Studio, оптимизированная для сенсорного ввода, появится в ближайшие годы.)

Visual Studio создаст решение с именем WinRTTestApp, проект WinRTTestApp в этом решении, а также набор файлов в проекте. Эти файлы перечислены в окне Solution Explorer в правой части экрана Visual Studio. Каждое решение Visual Studio содержит хотя бы один проект, но решение может содержать дополнительные проекты приложений и библиотек.

В список файлов этого проекта входит файл с именем MainPage.xaml. Щелкнув маленькой стрелке рядом с этим файлов вы увидите файл с именем MainPage.xaml.cs смещенный вправо от MainPage.xaml:

Структура проекта Windows Store в Visual Studio

Любой из этих двух файлов можно просмотреть - сделайте двойной щелчок на имени файла или же щелкните правой кнопкой мыши на имени и выберите команду Open.

Файлы MainPage.xaml и MainPage.xaml.cs включены в окно Solution Explorer, потому что каждый из них вносит свой вклад в определение класса MainPage. В простых программах, таких как наша, класс MainPage определяет все визуальные аспекты и пользовательский интерфейс приложения.

Несмотря на странное имя, файл MainPage.xaml.cs определенно имеет расширение .cs, то есть содержит код C#. Если убрать из файла все комментарии, базовый код C# в MainPage.xaml.cs выглядит так:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace WinRTTestApp
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
    }
}

Большое место в этом файле занимают директивы using для всех пространств имен, которые, как предполагается, понадобятся для работы программы. Впрочем, в большинстве файлов MainPage.xaml.cs нужны не все перечисленные пространства имен, а во многих файлах требуются дополнительные пространства.

Пространства имен делятся на две общие категории по префиксу имени:

Как можно предположить по виду списка директив using, пространства имен, начинающиеся с Windows.UI.Xaml, играют важную роль в работе Windows Runtime.

После директив using в файле MainPage.xaml.cs определяется пространство имен с именем WinRTTestApp (тем же, что и в имени проекта) и класс MainPage, производный от Page - класса, который является частью Windows Runtime.

Документация Windows 8 API упорядочена по пространствам имен. Если вы хотите найти документацию класса Page, информация о пространстве имен, в котором этот класс определен, упростит поиск. Наведите указатель мыши на имя Page в исходном коде MainPage.xaml.cs; вы увидите, что класс Page находится в пространстве имен Windows.UI.Xaml.Controls (вы можете нажать клавишу F1 в Visual Studio для загрузки описания класса на MSDN).

Конструктор класса MainPage вызывает метод InitializeComponent() (о котором мы вскоре поговорим подробнее).

Обратите внимание на ключевое слово partial в определении класса MainPage. Это ключевое слово обычно означает, что определение класса продолжается в другом файле с исходным кодом C#. Как вы вскоре убедитесь, в нашем случае дело обстоит именно так, однако недостающей частью класса MainPage является не другой файл с кодом C#, а файл MainPage.xaml:

<Page
    x:Class="WinRTTestApp.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:WinRTTestApp"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    </Grid>
</Page>

Файл состоит из разметки в стандарте, известном как XAML (extensible Application Markup Language - расширяемый язык разметки приложений) - произносится «зэмл». И как подсказывает название, XAML происходит от языка XML.

Обычно файл в формате XAML используется для определения визуальных элементов страницы, а файл C# делает то, что нельзя сделать в разметке - например, обрабатывает данные и реагирует на ввод данных пользователем. Файл C# часто называют файлом отделенного кода (code-behind file) для соответствующего файла XAML. Подобная модель компоновки приложений принята во многих архитектурных платформах .NET (WPF, Silverlight, ASP.NET Web Forms) и должна быть вам знакома, если вы с ними работали.

Корневой элемент файла XML - Page - уже известен вам как класс Windows Runtime. Но обратите внимание на атрибут:

x:Class="WinRTTestApp.MainPage"

Атрибут x:Class может присутствовать только в корневом элементе файла XAML. Этот конкретный атрибут означает «класс с именем MainPage в пространстве имен WinRTTestApp определяется как производный от Page». Он означает то же, что и определение класса в файле C#!

Далее следуют объявления пространств имен XML. Как обычно, эти URI не подразумевают фактического обращения к веб-страницам, а служат уникальными идентификаторами, поддерживаемыми некоторыми компаниями или организациями. Первые два пространства особенно важны:

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

В 2006 году компания Microsoft представила Windows Presentation Foundation; тогда же состоялся дебют XAML. Технология WPF была частью платформы .NET Framework 3.0, которая до выпуска обозначалась сокращением WinFX, отсюда и «winfx» в URI. Файлы XAML в определенной степени совместимы с WPF, Silverlight, Windows Phone и Windows Runtime, но только в том случае, если они используют классы, свойства и функции, общие для всех сред.

Первое объявление пространства имен без префикса относится к открытым классам, структурам и перечислениям, определенным в Windows Runtime; в эту категорию входят все элементы управления и вообще все, что может включаться в файл XAML, включая классы Page и Grid конкретного файла. Слово представление (presentation) в URI относится к визуальному пользовательскому интерфейсу, и это отличает его от других типов приложений, использующих XAML. Например, при использовании XAML для Windows Workflow Foundation (WF) в конце URI пространства имен по умолчанию стояло бы слово «workflow».

Второе объявление пространства имен связывает префикс «x» с элементами и атрибутами, принадлежащими XAML. Только девять из них могут использоваться в приложениях Windows Runtime; и конечно, самым важным является атрибут x:Class.

Третье объявление пространства имен выглядит интереснее:

xmlns:local="using:WinRTTestApp"

Оно связывает префикс XML local с пространством имен WinRTTestApp данного конкретного приложения. Если вы создадите в своем приложении пользовательские классы, для обращения к ним в XAML будет использоваться префикс local. Если вам потребуется обращаться к классам из библиотек программного кода, вы определите дополнительные объявления пространств имен XML с указанием имен сборок и пространств имен этих библиотек. Позднее вы увидите, как это делается.

Оставшиеся объявления пространств имен предназначены для Microsoft Expression Blend. Expression Blend может вставлять собственную разметку, которая должна игнорироваться компилятором Visual Studio; отсюда атрибут ignorable, требующий еще одного объявления пространства имен. В любой программе из последующих примеров три последних строки корневого элемента Page можно удалить.

У элемента Page имеется дочерний элемент с именем Grid - еще один класс, определенный в пространстве имен Windows.Ul.Xaml.Controls. Иногда его называют «контейнером», так как Grid может содержать другие визуальные объекты, но формально правильнее называть его «панелью», так как он является производным от класса Panel. Классы, производные от Panel, играют очень важную роль в структуре макета приложений Windows 8 и определяют их компоновку. В файле MainPage.xaml, который Visual Studio создает за вас, элементу Grid назначается цвет фона (на самом деле объект Brush) с использованием заранее определенного идентификатора и синтаксиса, используя ресурсы.

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

Для вывода абзаца текста в Windows Runtime обычно используется элемент управления TextBlock (еще один класс, определенный в пространстве имен Windows.UI.Xaml.Controls). Давайте разместим элемент TextBlock в Grid с одной ячейкой и назначим ему набор атрибутов. В действительности эти атрибуты являются свойствами, определяемыми классом TextBlock:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <TextBlock Text="Привет, Windows 8!" 
            FontSize="80"
            FontStyle="Italic"
            FontFamily="Arial"
            Foreground="LimeGreen"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            />
</Grid>

Порядок следования атрибутов роли не играет, как, разумеется, и отступы. Если вы очень торопитесь, все атрибуты, кроме Text, можно опустить. В процессе ввода текста функция Visual Studio IntelliSense предлагает имена атрибутов и возможные значения. Часто достаточно выбрать нужный вариант из списка. А когда вы завершаете ввод TextBlock, в представлении конструирования (конструктор представления, design view) Visual Studio отображается внешний вид страницы.

Также можно обойтись вообще без ввода, просто перетащить TextBlock из палитры инструментов Toolbox в Visual Studio, а затем задать свойства в таблице, но я так поступать не стану. Процесс создания программ будет описываться так, словно мы с вами вводим код и разметку с клавиатуры, как настоящие программисты.

Программу можно запустить в эмуляторе с возможностью управления разрешением, ориентацией и другими характеристиками. На панели инструментов Visual Studio находится раскрывающийся список, в котором выбрана строка Local Machine; замените ее строкой Simulator. Нажмите F5, чтобы откомпилировать и запустить программу, или выберите команду Start Debugging в меню Debug. Даже такие простые программы желательно запускать в отладчике Visual Studio:

Запуск тестового приложения в эмуляторе Windows Runtime

Атрибуты HorizontalAlignment и VerticalAlignment элемента TextBlock обеспечили выравнивание текста по центру, а вам как программисту не пришлось явно определять размер отображаемой области и размер выводимого текста. Также атрибуту HorizontalAlignment можно задать значение Left или Right, а атрибуту VerticalAlignment - значение Тор или Bottom, чтобы разместить TextBlock в одном из девяти мест Grid. Windows Runtime поддерживает возможность точного размещения визуальных объектов в пикселах, но обычно лучше использовать встроенные средства формирования макета.

У элемента TextBlock есть свойства Width и Height, но обычно задавать их не обязательно. Более того, задание свойств Width и Height в этом конкретном случае может привести к отсечению части текста или нарушению выравнивания текста по центру страницы. Элемент TextBlock умеет определять свои размеры лучше вас.

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

Чтобы завершить выполнение программы, нажмите клавиши Shift+F5 в Visual Studio или выберите команду Stop Debugging в меню Debug. Вы увидите, что программа не только была выполнена, но и стала доступной на начальном экране. Если вы сами создали проект, плитка выглядит не слишком впечатляюще, однако плитки программы хранятся в каталоге Assets проекта, так что при желании вы можете украсить их. Программу можно повторно запустить вне отладчика Visual Studio прямо с начального экрана Windows 8.

Графическое приветствие

Традиционные программы «Hello world» выводят приветствие в текстовом виде, но это не единственный вариант. Давайте используем растровое изображение с моего веб-сайта при помощи крошечного фрагмента разметки XAML:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Image Source="http://professorweb.ru/my/windows8/rt/level1/files/win8logo.png" />
</Grid>

Элемент Image определен в пространстве имен Windows.UI.Xaml.Controls; это стандартный механизм вывода растровых изображений в программах Windows Runtime. По умолчанию изображение масштабируется так, чтобы заполнить все выделенное место с сохранением исходных пропорций. При уменьшении страницы (например, из-за изменения ориентации устройства или активизации режима Snap View) размеры изображения изменяются в соответствии с новыми размерами страницы. Стандартный режим вывода изображения можно изменить при помощи свойства Stretch элемента Image. По умолчанию используется значение перечисляемого типа Stretch.Uniform. Попробуйте заменить его на Fill - изображение будет заполнять контейнер без сохранения пропорций:

Использование изображения в WinRT

Если свойство Stretch равно None, изображение выводится с исходными размерами (800 х 450). Местонахождением изображения на странице можно управлять при помощи тех же свойств HorizontalAlignment и VerticalAlignment, которые используются с TextBlock. При четвертом значении свойства Stretch - UniformToFill - контейнер заполняется с сохранением пропорций изображения. Это может быть сделано только одним способом: обрезкой изображения. Выбор отсекаемой части зависит от свойств HorizontalAlignment и VerticalAlignment.

Загрузка растрового изображения по сети зависит от наличия сетевого подключения, и даже при его наличии может потребовать некоторого времени. Чтобы гарантировать доступность изображения, лучше включить его в само приложение. Windows Runtime поддерживает популярные графические форматы BMP, JPEG, PNG и GIF, а также некоторые менее распространенные форматы. Для таких изображений, как наше, чаще всего используется формат PNG; сохраните его под именем win8logo.png.

Обычно для хранения растровых изображений, используемых проектом, используется каталог с именем Images. В окне Solution Explorer щелкните правой кнопкой мыши на имени проекта, выберите команды Add и New Folder. (Или если проект выделен в Solution Explorer, выберите команду New Folder в меню Project.) Введите имя папки, например, Images.

Теперь щелкните правой кнопкой мыши на папке Images, выберите команды Add и Existing Item. Перейдите к сохраненному ранее файлу win8logo.png и щелкните на кнопке Add. Когда файл будет добавлен в проект, щелкните правой кнопкой мыши на имени файла и выберите команду Properties. Убедитесь в том, что на панели свойств в поле Build Action выбран пункт Content - изображение должно стать частью содержимого приложения.

Файл XAML со ссылкой на изображение очень похож на аналогичный файл для обращения к изображению в Интернете:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Image Source="Images/win8logo.png" Stretch="Fill"/>
</Grid>

Обратите внимание: в свойстве Source указывается папка и имя файла. Некоторые программисты предпочитают хранить графику, используемую в приложении, в папке с именем Assets. В стандартный проект включается папка Assets с изображениями логотипа приложения; вы можете использовать ее для своих изображений, вместо того чтобы создавать отдельную папку.

Пройди тесты
Лучший чат для C# программистов