Каждый разработчик Windows Store приложений должен знать гайдлайны.
Guideline в переводе с английского — рекомендации, руководящие указания. Для того, чтобы приложение попало в Store не обязательно следовать рекомендациям, но следовать им желательно. Есть несколько особенностей, или иноземно выражаясь фич (англ. feature), которые желательно иметь каждому приложению. Я решил рассмотреть эти особенности, а заодно сделать шаблон C#/XAML приложения Windows Store, с которого можно начинать разработку. Ведь, так или иначе, часто приходится заходить в разработанные ранее приложения или MSDN, чтобы скопировать код сниппета для определенной функции.
Описанные далее возможности не только сделают ваше приложение соответствующим гайдлайнам, но и украсят его дополнительным функционалом, привлекающим внимание пользователей, а также помогут в продвижении.
Контракт Share
Для того, чтобы пользователь мог отправить e-mail друзьям или поделиться информацией о приложении/игре в социальной сети, в код приложения нужно добавить контракт share. Для того чтобы это сделать следуем следующим действиям.
Добавляем пространство имен:
using Windows.ApplicationModel.DataTransfer;
И в классе страницы добавляем объявление переменной:
private DataTransferManager dataTransferManager;
Далее переопределяем события захода на страницу и выхода с нее:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
//регистрируем страницу как источник share
this.dataTransferManager = DataTransferManager.GetForCurrentView();
this.dataTransferManager.DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(this.DataRequested);
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
// удаляем регистрацию
this.dataTransferManager.DataRequested -= new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(this.DataRequested);
}
Простейший вариант контента, которым можно поделиться это заголовок, текст и ссылка:
private void DataRequested(DataTransferManager sender, DataRequestedEventArgs e)
{
Uri dataPackageUri = new Uri("http://apps.microsoft.com/windows/ru-ru/app/mp3/0122ffd9-585f-4b3d-a2ad-571f74231d14");
DataPackage requestData = e.Request.Data;
requestData.Properties.Title = "Прикольная игра";
requestData.SetWebLink(dataPackageUri);
requestData.Properties.Description = "И здесь добавить какое-то описание.Как правило, текст содержит рекомендацию установить приложение.";
}
Также можно отправить файл или изображение. Есть вариант, при котором сообщение может быть отправлено в формате HTML.
Поделиться из Windows 8.1 можно вызвав волшебную charm панельку и выбрав в ней вот такой значок:
В Windows 10 поделиться контентом можно нажав такой же значок в верхнем левом углу приложения:
Для того, чтобы открыть окно программно из кода, можно воспользоваться следующей строчкой:
Windows.ApplicationModel.DataTransfer.DataTransferManager.ShowShareUI();
Официальное руководство доступно по ссылке:
Краткое руководство: общий доступ к содержимому (XAML)
Live tile
Наверняка вы замечали, что некоторые плитки на стартовом экране изменяются со временем. Взять, к примеру, тайлы новостных сайтов или же тайл приложения «Финансы», который сам обновляет сводки. Некоторые тайлы меняются каждые несколько секунд, привлекая тем самым внимание пользователя. Это так называемые «живые» плитки/тайлы.
Для того, чтобы приложение изменило тайл ему можно послать push уведомление, но можно обновить тайл и из самого приложения.
Для того, чтобы обновить тайл из приложения, первым делом нужно добавить пространство имен
using Windows.UI.Notifications;
Далее напишем простой метод, который изменит вид и текст тайла:
void UpdateTileWithText()
{
// # обновление квадратного тайла
var tileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare150x150Text04);
var tileAttributes = tileXml.GetElementsByTagName("text");
string tiletext = "Какой - либо текст для отображения на тайле";
tileAttributes[0].AppendChild(tileXml.CreateTextNode(tiletext));
var tileNotification = new TileNotification(tileXml);
tileNotification.ExpirationTime = DateTimeOffset.UtcNow.AddHours(1);
TileUpdateManager.CreateTileUpdaterForApplication().Update(tileNotification);
}
В примере, в качестве шаблона использован тайл с четырьмя строками текста. Все шаблоны доступны по ссылке: Каталог шаблонов плиток
По гайдлайнам очень рекомендуется, чтобы у приложения были плитки и квадратного и широкого размера, поэтому желательно этот же код дублировать, указав в виде шаблона тайла уже не квадратный, а широкий шаблон. То есть в примере заменить TileTemplateType.TileSquare150x150Text04 на TileTemplateType.TileWide310x150Text04.
У себя в приложении я обновлял тайл при событии App_Suspending, для того, чтобы напомнить пользователям на чем они остановились, но можно делать это в любой другой момент.
Если нужно очистить изменения, которые были совершены и вернуть тайл к первоначальному виду, то сделать это можно из кода строчкой:
TileUpdateManager.CreateTileUpdaterForApplication().Clear();
Официальная, хоть и краткая, но чуть более полная инструкция доступна по ссылке:
Краткое руководство: отправка обновления плитки (XAML)
Rate and Review
Рекомендуется ненавязчиво предлагать пользователям оценить ваше приложение. Хорошие оценки и отзывы помогут повысить популярность вашего предложения. Кроме того отзывы пользователей позволяют вам своевременно и с пользой делать изменения функционала и дизайна приложения. Для того, чтобы открыть окно Windows Store с оценкой достаточно создать и открыть URI. Для этого достаточно двух строчек:
var uri = new Uri("ms-windows-store:Review?PFN=9cc1e6dd-9d82-4736-aee5-acb9a01d9c39_1dv79ndb6c382");
await Windows.System.Launcher.LaunchUriAsync(uri);
Обратите внимание на то, что открытие страницы происходит асинхронно с использованием await. Раз так, то к процедуре нажатия кнопки необходимо будет добавить предикат async.
Сформировать URI относительно просто. К тексту «ms-windows-store:Review?PFN=» нужно добавить Package Family Name или сокращенно PFN. Его значение можно узнать, открыв манифест приложения.
Ссылка на официальное руководство как сформировать ссылку на приложение в Store:
Linking to your app
Ссылку указал на английском, так как в русском переводе перевели по ошибке еще и ключевые слова.
Так как шаблон мы пишем под 8.1 а не под 10, то есть одна небольшая путаница. Способ формирования URI для WP 8.1 немного отличается от способа формирования URI для Windows Store приложений. Для WP 8.1 URI выглядит вот так:
ms-windows-store:reviewapp?appid=cq23k522-7u59-1193-h4aa-3t56e4633c24
Официальное руководство (на русском):
Ссылка на ваше приложение в Магазине
Довольно хорошим способом получить оценку и отзыв пользователя может быть предложение оценить приложение после определенного количества запусков. Будем считать, что раз пользователь запустил приложение, скажем, 5 раз, то ему есть что сказать о приложении.
Количество запусков приложения можно сохранять с помощью настроек приложения. Заодно и разберемся с тем, как сохранять настройки.
Settings
Простой сниппет, с помощью которого можно считать сколько раз приложение было запущено:
В объявления переменных добавим:
int appRunCount = 0;
Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
В конструктор класса страницы после this.InitializeComponent(); добавим:
try
{
appRunCount = (int)localSettings.Values["AppRunCount"];
}
catch { }
appRunCount++;
try
{
localSettings.Values["AppRunCount"] = appRunCount;
}
catch { }
Таким образом мы получим в переменной appRunCount количество запусков приложения.
Вместо Windows.Storage.ApplicationData.Current.LocalSettings мы можем использовать Windows.Storage.ApplicationData.Current.RoamingSettings. Если сделать так, то мы сможем сохранять настройки не локально на устройстве, а в роуминге, т.е. в сети. Они сохраняются в пользовательском аккаунте Microsoft. RoamingSettings будут доступны с любого устройства, на котором был совершен вход из одного и того же аккаунта.
Простой код, которым выдается сообщение в случае, если приложение запущено 5-ый раз и в случае согласия пользователя поставить оценку открывается окошко магазина с предложением оставить отзыв:
if (appRunCount == 5)
{
var messageDialog = new Windows.UI.Popups.MessageDialog("Оставьте, пожалуйста, отзыв о приложении", "Проголосуйте за нас!");
// можем добавить не больше трех команд/вариантов выбора
messageDialog.Commands.Add(new Windows.UI.Popups.UICommand("Поставить оценку", new Windows.UI.Popups.UICommandInvokedHandler(CommandHandler)));
messageDialog.Commands.Add(new Windows.UI.Popups.UICommand("Я уже ставил оценку", new Windows.UI.Popups.UICommandInvokedHandler(CommandHandler)));
messageDialog.Commands.Add(new Windows.UI.Popups.UICommand("В другой раз", new Windows.UI.Popups.UICommandInvokedHandler(CommandHandler)));
messageDialog.DefaultCommandIndex = 0;
messageDialog.CancelCommandIndex = 2;
await messageDialog.ShowAsync();
}
private async void CommandHandler(IUICommand command)
{
if (command.Label=="Поставить оценку")
{
var uri = new Uri("ms-windows-store:PDP?PFN=9cc1e6dd-9d82-4736-aee5-acb9a01d9c39_1dv79ndb6c382");
await Windows.System.Launcher.LaunchUriAsync(uri);
}
}
Окошко с вопросом выглядит стандартным и слишком обычным. В идеале, лучше сделать свой PopUp, который будет обладать дизайном, вписывающимся в дизайн приложения. Но это уже выходит за рамки, рассматриваемые этой статьей.
Как сохранить настройки приложения мы разобрались.
Вот где можно почитать официальное руководство:
Загрузка и сохранение параметров
Для того, чтобы пользователь мог изменить какие-то настройки в Modern UI приложениях есть возможность создать «вылетающую» панельку – Flyout
Settings Flyout
Такая возможность доступна только для приложений Windows 8.1 и 10. В Windows 8 при желании создать аналогичную панельку было возможно, но необходимо было создавать свой user control.
Для того, чтобы добавить в приложение «вылетающую» панельку с настройками в проект необходимо добавить новый элемент управления под названием Settings Flyout (в русскоязычном варианте «Всплывающий элемент параметров»). Порядок действий следующий. Заходим в меню:
Project – Add New Item… — Visual C# — XAML – Settings Flyout
или
Проект — Добавить новый элемент — Visual C# — XAML – Всплывающий элемент параметров
Назовем новый элемент, например, так: CustomSettingsFlyout.xaml
Добавляем в App.xaml.cs приложения ссылки на пространства имен:
using Windows.UI.ApplicationSettings;
using Windows.UI.Popups;
И следующий код:
protected override void OnWindowCreated(WindowCreatedEventArgs args)
{
SettingsPane.GetForCurrentView().CommandsRequested += OnCommandsRequested;
}
private void OnCommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args)
{
SettingsCommand settingsCommand = new SettingsCommand("SettingsPage", "Open settings",new UICommandInvokedHandler(onSettingsCommand));
args.Request.ApplicationCommands.Add(settingsCommand);
}
private void onSettingsCommand(IUICommand command)
{
CustomSettingsFlyout settingsFlyout = new CustomSettingsFlyout();
settingsFlyout.Show();
}
Теперь при вызове настроек приложения у нас будет отображено наше окно. Можем править код XAML и C# нашего элемента CustomSettingsFlyout так как нам нужно.
Сохранять настройки мы только что научились с помощью класса Windows.Storage.ApplicationData.Current.LocalSettings
Официальный мануал:
Краткое руководство: добавление параметров приложения (XAML)
Всплывающие уведомления
Для того, чтобы уведомить пользователя о чем-либо, можно отобразить toast уведомление. Это небольшой прямоугольник с картинкой и текстом, которые выплывает справа, подобно Flyout. Toast уведомление не блокирует интерфейс приложения в отличие от MessageBox-а. Довольно удобно будет, если у нас в коде вызов уведомления будет заключен в отдельном методе. Добавляем еще 2 пространства имен:
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
И добавим сам метод, после вызова которого с текстом в качестве параметра мы получим уведомление:
void ShowToast(string whattext)
{
XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText01);
XmlNodeList stringElements = toastXml.GetElementsByTagName("text");
stringElements[0].AppendChild(toastXml.CreateTextNode(whattext));
ToastNotification toast = new ToastNotification(toastXml);
toast.Activated += ToastActivated;
toast.Dismissed += ToastDismissed;
toast.Failed += ToastFailed;
ToastNotificationManager.CreateToastNotifier().Show(toast);
}
Первой строкой мы задаем значением xml шаблон ToastText01. Это довольно простой шаблон, который содержит в себе только текст, занимающий 3 строки.
Все возможные шаблоны здесь: Каталог шаблонов всплывающих уведомлений
Еще вы можете заметить, что мы подписываемся на 3 события: активацию уведомления, скрытие уведомления и ошибку уведомления. Теперь на обязательно нужно реализовать обработчики этих событий (пусть даже и без кода):
private void ToastFailed(ToastNotification sender, ToastFailedEventArgs args) { }
private void ToastDismissed(ToastNotification sender, ToastDismissedEventArgs args) { }
private void ToastActivated(ToastNotification sender, object args) { }
Официальное руководство:
Краткое руководство: отправка всплывающего уведомления (XAML)
AppBar и CommandBar
Напоследок, добавим в приложение панель со стандартными элементами управления.
Панель может быть верхней или нижней. Кнопки команд и инструментов принято размещать на нижней панели.
Панель можно создать в XAML следующими тэгами:
<Page.TopAppBar>
<!-- content -->
</Page.TopAppBar>
Или
<Page.BottomAppBar>
<!-- content -->
</Page.BottomAppBar>
Содержимым панели может быть элемент AppBar (для различных контролов, кои ваша душенька пожелает разместить) или элемент CommandBar (только для кнопок – XAML элементов AppBarButton, AppBarToggleButton и AppBarSeparator). Для обычного приложения вполне достаточно обычных кнопок, поэтому ограничимся CommandBar-ом. Код такой:
<Page.BottomAppBar>
<CommandBar IsOpen="True">
<AppBarButton Label=" Vote and review" Icon="Like" Click="ReviewButton_Click"/>
<AppBarButton x:Name="btnSecTile" Label="Add to Start" Click="btnSecTile_Click" Icon="Pin"/>
<CommandBar.SecondaryCommands>
<AppBarButton Label="Share" Icon="OtherUser" Click="ShareButton_Click"/>
</CommandBar.SecondaryCommands>
</CommandBar>
</Page.BottomAppBar>
Обратите внимание на атрибут IsOpen=”True”. При открытии приложения желательно отобразить панель, дабы пользователь был в курсе ее наличия и соответственно знал какие возможности есть у приложения. Также вы можете заметить вложенный тег CommandBar.SecondaryCommands которые содержит в себе кнопки, которые будут отражены слева панели. Они как бы второстепенные.
Официальное руководство:
Краткое руководство: добавление панелей приложения (XAML)
Secondary tile
Есть возможность разрешить пользователю закрепить вспомогательную плитку/тайл на стартовый экран Windows. По нажатию этой плитки приложение может открываться с определенными параметрами, также вспомогательный тайл может быть «живым» (т.е. live тайлом) и отображать какие-либо специальные оповещения.
Сперва, чтобы добавить secondary tile, мы добавим необходимое отсутствующее пространство имен:
using Windows.UI.StartScreen;
в конструктор страницы после InitializeComponent(); добавляем вызов метода с параметром:
ToggleAppBarButton(!SecondaryTile.Exists("MyUnicTileID"));
Здесь MyUnicTileID это уникальный идентификатор тайла
Далее нам нужно добавить сам метод ToggleAppBarButton, который будет отображать значок прикрепить или открепить в зависимости от текущего состояния вспомогательной плитки.
public void ToggleAppBarButton(bool showPinButton)
{
if (showPinButton)
{
btnSecTile.Label = "Прикрепить";
btnSecTile.Icon = new SymbolIcon(Symbol.Pin);
}
else
{
btnSecTile.Label = "Открепить";
btnSecTile.Icon = new SymbolIcon(Symbol.UnPin);
}
this.btnSecTile.UpdateLayout();
}
Здесь showPinButton это булева переменная, которая хранит значение передаваемое !SecondaryTile.Exists(«MyUnicTileID»), т.е. прикреплен ли вспомогательный тайл приложения к стартовому экрану или нет.
Теперь добавим код в событие нажатия кнопки. Этот код будет прикреплять плитку к начальному экрану или откреплять ее:
private async void btnSecTile_Click(object sender, RoutedEventArgs e)
{
Windows.Foundation.Rect rect = GetElementRect((FrameworkElement)sender);
if (SecondaryTile.Exists("MyUnicTileID"))
{
SecondaryTile secondaryTile = new SecondaryTile("MyUnicTileID");
bool isUnpinned = await secondaryTile.RequestDeleteForSelectionAsync(rect, Windows.UI.Popups.Placement.Above);
ToggleAppBarButton(isUnpinned);
}
else
{
// Pin
Uri square150x150Logo = new Uri("ms-appx:///Assets/Logo.scale-100.png");
string tileActivationArguments = "Secondary tile was pinned at = " + DateTime.Now.ToLocalTime().ToString();
string displayName = "Application name";
TileSize newTileDesiredSize = TileSize.Square150x150;
SecondaryTile secondaryTile = new SecondaryTile("MyUnicTileID",
displayName,
tileActivationArguments,
square150x150Logo,
newTileDesiredSize);
secondaryTile.VisualElements.Square30x30Logo = new Uri("ms-appx:///Assets/SmallLogo.scale-100.png");
secondaryTile.VisualElements.ShowNameOnSquare150x150Logo = true;
secondaryTile.VisualElements.ForegroundText = ForegroundText.Light;
bool isPinned = await secondaryTile.RequestCreateForSelectionAsync(rect, Windows.UI.Popups.Placement.Above);
ToggleAppBarButton(!isPinned);
}
}
Также вам нужно добавить функцию
public static Rect GetElementRect(FrameworkElement element)
{
GeneralTransform buttonTransform = element.TransformToVisual(null);
Point point = buttonTransform.TransformPoint(new Point());
return new Rect(point, new Size(element.ActualWidth, element.ActualHeight));
}
Примерно такое вот предупреждение вы должны получить при закреплении плитки на начальный экран:
«App Template» — это название приложения. Вы можете или закрепить плитку или отказаться, кликнув где-либо свободном месте приложения и закрыв тем самым pop-up.
Как обычно, ссылка на официальное руководство:
Краткое руководство. Закрепление вспомогательной плитки (XAML)
Это были некоторые из возможностей Windows Store приложений. Очень рекомендую их использовать.
Получившийся шаблон вы можете скачать по ссылке с GitHub:
https://github.com/programmersommer/WindowsStoreAppTemplate
или в качестве архива zip (версия с русскими комментариями):
OneDrive