Статьи

Создание вашего первого универсального приложения для Windows

Универсальные приложения Windows позволяют вам ориентироваться на каждое устройство Windows в одном решении. Вы разрабатываете один раз, делитесь большей частью своего кода и развертываете в Windows, Windows Phone или Xbox.

Цель состоит в том, чтобы максимизировать повторное использование кода. Вы можете совместно использовать код, пользовательские элементы управления, стили, строки и другие ресурсы между проектами Windows Phone и Windows 8 в Visual Studio. Это уменьшает усилия, необходимые для создания и поддержки приложения для каждого типа устройства.

С точки зрения разработчика, универсальное приложение для Windows — это не отдельный двоичный файл, работающий на нескольких платформах. Скорее, он принимает форму решения Visual Studio, содержащего несколько проектов, по одному проекту для каждой целевой платформы в дополнение к общему проекту, содержащему код и ресурсы, совместно используемые платформами. Большая часть кода может быть разделена между проектами, так как Windows Phone 8.1 реализует большинство API WinRT, которые реализует Windows 8.1.

Вы можете создать приложение для Windows Phone, используя среду выполнения Silverlight (версия 8.0 или 8.1) или среду выполнения WinRT (из универсальных приложений Windows). Среда выполнения WinRT позволяет вам создать одно приложение, которое будет работать в Windows, Windows Phone и даже Xbox One.

Мы используем платформу XAML для разработки приложения для нескольких платформ. В текущей версии API конвергенции составляет 90%, но есть небольшой набор, который еще не конвергирован. Функции Windows Phone, доступные только в платформе Silverlight:

  • Поддержка линз
  • Поддержка VoIP
  • Задача захвата камеры
  • API буфера обмена
  • API экрана блокировки экрана

В этом уроке я буду использовать универсальный шаблон приложения для Windows, чтобы создать приложение Hex Clock, точные шестнадцатеричные цветные часы. Он проходит весь 24-часовой диапазон цветов, от # 000000 до # 235959 . С каждым тактом часов фон приложения меняется на цвет, соответствующий текущему времени, преобразованному в шестнадцатеричное. Он использует ту же реализацию, что и Hex Color JS Clock, для генерации шестнадцатеричного кода текущего времени.

Дизайн был навеян учебником по часовым приложениям для Windows Phone 7 на Tuts + . Хотя приложение часов предназначено только для Windows Phone, мы будем использовать его дизайн для создания аналогичного приложения для Windows Phone 8.1 и Windows 8.1. На скриншоте ниже показано, что мы собираемся построить.

Окончательное изображение того, как будут выглядеть шестнадцатеричные часы

В этом руководстве я расскажу о следующих темах, которые имеют отношение к разработке универсальных приложений для Windows:

  • структура универсальных приложений для Windows
  • переключение запуска проектов в Visual Studio
  • переключатель контекста для универсальных приложений Windows в редакторе Visual Studio
  • как написать кроссплатформенный код в общем проекте
  • как добавить поддержку Windows или Windows Phone в существующий проект
  • создание универсального приложения для Windows с нуля

Универсальное приложение для Windows — это коллекция из трех проектов, заключенных в дополнительную папку решения. Проекты Windows и Windows Phone являются проектами платформ и отвечают за создание пакетов приложений (.appx), ориентированных на соответствующие платформы. Эти проекты содержат ресурсы, специфичные для целевой платформы.

Общий проект — это контейнер для кода, который выполняется на обеих платформах. У них нет двоичного вывода, но их содержимое импортируется проектами платформы и используется как часть процесса сборки для генерации пакетов приложения (.appx).

На приведенном ниже снимке экрана показано решение, которое Visual Studio создает при выборе шаблона проекта для пустого приложения (универсальные приложения).

Структура универсального приложения

В обновлении 2 для Visual Studio 2013 представлена ​​новая функция — универсальные приложения Windows. Загрузите и установите это обновление, прежде чем приступить к созданию универсальных приложений для Windows.

Когда вы запускаете решение, запускается проект, который выбирается в качестве запускаемого проекта. Чтобы настроить стартовый проект, щелкните правой кнопкой мыши узел проекта в обозревателе решений и выберите параметр « Установить как стартовый проект» . Вы можете быстро переключить стартовый проект из выпадающего списка цели отладки , который теперь перечисляет все возможные проекты в решении.

Переключение запуска проектов

Выбранный вами проект выделен жирным шрифтом в обозревателе решений . Доступные цели отладки изменяются при переключении запускаемых проектов.

  • Когда проект Windows является стартовым, в раскрывающемся списке «Цель отладки» отображаются параметры для симулятора Windows или локального компьютера .
  • Когда проект Windows Phone является проектом запуска, раскрывающийся список отображает параметры устройства, а также различные эмуляторы.

При написании кода в общем проекте вы можете использовать переключатель контекста проекта на панели навигации, чтобы выбрать платформу, на которую вы активно нацеливаетесь, что, в свою очередь, настраивает работу IntelliSense в редакторе кода.

Переключатель контекста в редакторе

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

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

Пример значков предупреждений и Intellisense

В общем проекте вы обычно пишете код, общий для обеих платформ. Чтобы изолировать участки кода, которые зависят от платформы, используйте директиву #ifdef . Константы WINDOWS_APP и WINDOWS_PHONE_APP предопределены для вас.

Ниже приведены константы условной компиляции, которые можно использовать для написания кода, специфичного для платформы:

C # WINDOWS_APP WINDOWS_PHONE_APP
C ++ WINAPI_FAMILY_PC_APP WINAPI_FAMILY_PHONE_APP

Когда вы пишете код в общем проекте, редактор кода Visual Studio использует контекст, предназначенный для одной или другой платформы. В C # IntelliSense, который вы видите при написании кода, зависит от контекста редактора кода, то есть от Windows или Windows Phone.

Если у вас уже есть приложение Windows 8.1, вы можете использовать команду « Добавить Windows Phone 8.1», чтобы добавить новый проект Windows Phone 8.1 и общий проект в решение. Аналогичная опция также доступна, если у вас есть приложение для Windows Phone 8.1, и вы хотите добавить поддержку Windows 8.1.

Чтобы добавить поддержку того или иного типа устройства, в обозревателе решений щелкните правой кнопкой мыши проект и выберите « Добавить Windows Phone 8.1» или « Добавить Windows 8.1» .

Добавить приложение Windows 81 в существующий проект Windows Phone 81

Здесь Visual Studio добавляет новый проект Windows Phone или Windows к решению. Общий проект также автоматически создается для вас.

На следующем снимке экрана показано решение после добавления проекта Windows Phone в существующий проект Windows. Общий проект, который добавляется в решение, изначально пуст.

Структура проекта после добавления проекта Windows 81 в существующее приложение Windows Phone 81

Обратите внимание, что если вы создаете приложение с использованием универсального шаблона приложения Windows, общий проект уже содержит файл App.xaml .

Вы можете переместить любой код, которым хотите поделиться между приложениями, в общий проект. Например, вы можете переместить папки Common , DataModel и Strings в общий проект. Вы даже можете переместить App.xaml в общий проект.

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

На следующем снимке экрана показана одинаковая ссылка на сборку, добавленная в оба проекта.

Добавление одинаковой ссылки на сборку для обоих проектов

Если ваш общий код использует API, специфичные для Windows, используйте директиву WINDOWS_APP константой WINDOWS_APP чтобы изолировать этот раздел кода. Используйте константу WINDOWS_PHONE_APP чтобы изолировать участки кода, специфичные для Windows Phone 8.1.

Когда вы создаете новое решение для универсального приложения Windows, Visual Studio помещает App.xaml в общий проект. Если вы преобразуете существующий проект в универсальное приложение Windows, вы можете вручную переместить App.xaml в общий проект. Вам нужно будет установить свойство действия сборки страницы на ApplicationDefinition после перемещения файла. Вот эти шаги:

  • В обозревателе решений в общем проекте выберите файл App.xaml .
  • Выберите « Вид» > « Свойства» .
  • В окне « Свойства» в раскрывающемся списке « Построить действие» выберите ApplicationDefinition .

Вы также должны решить, как вы хотите открыть первую страницу своего приложения. Если вы публикуете файл App.xaml и хотите использовать разные стартовые страницы для каждого приложения, вы должны добавить директивы #ifdef как показано ниже.

1
2
3
4
5
6
7
8
9
#if WINDOWS_APP
if (!rootFrame.Navigate(typeof(HubPage)))
#endif
#if WINDOWS_PHONE_APP
if (!rootFrame.Navigate(typeof(WindowsPhoneStartPage)))
#endif
{
    throw new Exception(«Failed to create initial page»);
}

Во-первых, выберите шаблон проекта для универсального приложения Windows в диалоговом окне « Новый проект ». На следующем снимке экрана показаны шаблоны проектов универсальных приложений Windows, которые в настоящее время доступны для C #.

Шаблоны универсальных приложений для Windows

Дайте проекту имя. Я буду использовать Hex Clock Pro для своего проекта.

По большей части работа с пользовательским интерфейсом происходит в проектах, ориентированных на платформу, что позволяет вам создавать пользовательский интерфейс, который отлично смотрится на ПК, планшетах и ​​телефонах, но имеет общие данные, ресурсы, компоненты и даже представления. моделей.

Вместо создания отдельных пользовательских интерфейсов для версий Hex Clock Pro для Windows Phone 8.1 и Windows 8.1 я определяю общий дизайн в общем проекте. Мне просто нужно внести несколько изменений в XAML приложения часов на Tuts +, чтобы оно работало на обеих платформах.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<Canvas x:Name=»ContentPanel» Margin=»12,0,620,0″ HorizontalAlignment=»Center» Grid.Row=»1″ RenderTransformOrigin=»0.5,0.5″>
    <Canvas.RenderTransform>
        <CompositeTransform Rotation=»-30″/>
    </Canvas.RenderTransform>
    <Canvas x:Name=»TimeText» Height=»315″ Canvas.Left=»-18″ Canvas.Top=»288″ Width=»496″ RenderTransformOrigin=»0.5,0.5″ Opacity=»0″>
        <Canvas.RenderTransform>
            <CompositeTransform/>
        </Canvas.RenderTransform>
        <TextBlock x:Name=»TimeHours» TextWrapping=»Wrap» Text=»12″ Canvas.Top=»24″ Style=»{StaticResource TimeTextStyle}» Canvas.Left=»-67″ Width=»267″ TextAlignment=»Right»/>
        <TextBlock x:Name=»TimeDots» Canvas.Left=»204″ TextWrapping=»Wrap» Text=»:» Style=»{StaticResource TimeTextStyle}»/>
        <TextBlock x:Name=»TimeMinutes» Canvas.Left=»263″ TextWrapping=»Wrap» Text=»59″ Canvas.Top=»24″ Style=»{StaticResource TimeTextStyle}» Width=»257″/>
    </Canvas>
    <Rectangle x:Name=»HorizontalSeparator» Height=»4″ Canvas.Left=»-400″ Canvas.Top=»295″ Width=»1020″ Fill=»White»/>
    <Rectangle x:Name=»VerticalSeparator» Fill=»White» Height=»469″ Canvas.Left=»213″ Canvas.Top=»489″ Width=»4″/>
    <TextBlock x:Name=»ApplicationTitle» TextWrapping=»Wrap» Text=»HEX CLOCK PRO» Canvas.Top=»271″ Foreground=»White» FontSize=»16″ Canvas.Left=»18″/>
    <TextBlock x:Name=»SecondsLabel» Height=»36″ Canvas.Left=»23″ TextWrapping=»Wrap» Text=»seconds» Canvas.Top=»475″ Width=»166″ TextAlignment=»Right» Style=»{StaticResource SmallTextStyle}» Margin=»0″/>
    <TextBlock x:Name=»TimeSeconds» Height=»205″ Canvas.Left=»3″ TextWrapping=»Wrap» Text=»59″ Canvas.Top=»505″ Width=»210″ FontSize=»186.667″ RenderTransformOrigin=»0.5,0.5″ Opacity=»0″>
        <TextBlock.RenderTransform>
            <CompositeTransform/>
        </TextBlock.RenderTransform>
    </TextBlock>
    <TextBlock x:Name=»DateText» Height=»39″ Canvas.Left=»208″ TextWrapping=»Wrap» Text=»2012/12/31″ Canvas.Top=»258″ Width=»143″ FontSize=»29.333″ Opacity=»0″/>
</Canvas>

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

Поскольку приложение Hex Clock Pro не использует API-интерфейсы, специфичные для платформы, я могу поместить весь код в общий проект.

В файле MainPage.xaml.cs в общем проекте мы использовали директиву #ifdef для изоляции кода, специфичного для Windows Phone. Код, заключенный в #ifdef скрывает строку состояния на Windows Phone.

1
2
3
4
5
6
7
public MainPage()
{
    this.InitializeComponent();
    #if WINDOWS_PHONE_APP
    ApplicationView.GetForCurrentView().SetDesiredBoundsMode(ApplicationViewBoundsMode.UseCoreWindow);
    #endif
}

Я использовал класс DispatcherTimer для вызова начального тика при LayoutRoot сетки LayoutRoot . Объект timer вызывает функцию timer_Tick на каждом тике часов.

1
2
3
4
5
6
7
8
9
try
{
    DispatcherTimer timer = new DispatcherTimer();
    timer.Tick += timer_Tick;
    timer.Interval = new TimeSpan(0, 0, 0, 1);
    timer.Start();
    timer_Tick(null, null);
}
catch { }

Функция timer_Tick обновляет отображаемое время в приложении и одновременно обновляет цвет фона.

Цвет фона устанавливается в шестнадцатеричном цвете, который соответствует текущему времени.

1
2
3
HexColour color = new HexColour(hexTime);
SolidColorBrush bgBrush = new SolidColorBrush(Color.FromArgb(color.A, color.R, color.G, color.B));
LayoutRoot.Background = bgBrush;

Объект класса HexColour инициализируется с текущим временем, возвращая соответствующие значения RGB. HexColour класса HexColour устанавливает значения A, R, G, B для указанного цвета.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public HexColour(string hexCode)
{
    if (hexCode == null)
    {
        throw new ArgumentNullException(«hexCode»);
    }
 
    if (!Regex.IsMatch(hexCode, HEX_PATTERN))
    {
        throw new ArgumentException(«Format must be #000000 or #FF000000 (no extra whitespace)», «hexCode»);
    }
 
    // shave off ‘#’ symbol
    hexCode = hexCode.TrimStart(‘#’);
 
    // if no alpha value specified, assume no transparency (0xFF)
    if (hexCode.Length != LENGTH_WITH_ALPHA)
        hexCode = String.Format(«FF{0}», hexCode);
 
    _color = new Color();
    _color.A = byte.Parse(hexCode.Substring(0, 2), NumberStyles.AllowHexSpecifier);
    if (_color.A < 50)
        _color.A = 50;
    _color.R = byte.Parse(hexCode.Substring(2, 2), NumberStyles.AllowHexSpecifier);
    _color.G = byte.Parse(hexCode.Substring(4, 2), NumberStyles.AllowHexSpecifier);
    _color.B = byte.Parse(hexCode.Substring(6, 2), NumberStyles.AllowHexSpecifier);
}

Я имитировал начальную анимацию, использованную в предыдущем приложении часов на Tuts +, и она инициализируется при LayoutRoot .

1
2
3
Storyboard sb = (Storyboard)this.Resources[«IntialAnimation»];
sb.BeginTime = TimeSpan.FromSeconds(0.1);
sb.Begin();

Это все, что нам нужно для создания приложения Hex Clock Pro. Приложение использует 100% общий код. Вам просто нужно сгенерировать отдельные пакеты приложений для обеих платформ. Приложение выглядит очень похоже на Windows Phone и использует тот же код XAML для своего пользовательского интерфейса.

Hex Clock Pro для Windows Phone 81

Обратите внимание, что я добавил весь код XAML и C # в общий проект, но при развертывании приложения Windows или приложения Windows Phone код в общем проекте объединяется внутри с проектами, специфичными для платформы.

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

Если бы я построил версию Hex Clock Pro для Windows Phone 7 или 8 для Windows Phone, было бы гораздо больше работы, так как Windows Phone 7 не содержит API WinRT, а Windows Phone 8 содержит только небольшое подмножество.

В Windows 10 мы увидим больше конвергенции, что означает один API — WinRT API — для нескольких платформ, и высокую степень точности между элементами пользовательского интерфейса для каждой платформы, что не мешает разработчикам использовать элементы платформы для представления лучший опыт на каждом устройстве. Не стесняйтесь загружать исходные файлы учебника для использования в качестве справочного материала. Hex Clock Pro также доступна на рынке для Windows Phone 8.1 и Windows 8.1 .