using Microsoft.Phone.Tasks;
Сразу после конструктора MainPage добавьте следующий код:
private void EMailMe_Click(object sender, RoutedEventArgs e)
{
EmailComposeTask compose = new EmailComposeTask();
compose.To = "rush4apps@microsoft.com";
compose.Body = "Крутая иннициатива! Я хочу участовать! Продлите акцию, пожлайста!";
compose.Show();
}
private void AppDetails_Click(object sender, RoutedEventArgs e)
{
//MarketplaceDetailTask marketDetails = new MarketplaceDetailTask();
//marketDetails.ContentType = MarketplaceContentType.Applications;
//marketDetails.ContentIdentifier = "введите сюда идентфикатор приложения";
//marketDetails.Show();
}
private void MarketHub_Click(object sender, RoutedEventArgs e)
{
MarketplaceHubTask marketHub = new MarketplaceHubTask();
marketHub.ContentType = MarketplaceContentType.Applications;
marketHub.Show();
}
private void MarketSearch_Click(object sender, RoutedEventArgs e)
{
MarketplaceSearchTask marketSearch = new MarketplaceSearchTask();
marketSearch.ContentType = MarketplaceContentType.Applications;
marketSearch.SearchTerms = "GPSInfo";
marketSearch.Show();
}
private void MediaPlayer_Click(object sender, RoutedEventArgs e)
{
//MediaPlayerLauncher player = new MediaPlayerLauncher();
//player.Controls = MediaPlaybackControls.Stop;
//player.Media = "укажите URI с которого будет играть контент";
//player.Show();
}
private void PhoneCall_Click(object sender, RoutedEventArgs e)
{
PhoneCallTask call = new PhoneCallTask();
call.DisplayName = "Главному разработчику";
call.PhoneNumber = "+7 555 555 5555";
call.Show();
}
private void Search_Click(object sender, RoutedEventArgs e)
{
SearchTask search = new SearchTask();
search.SearchQuery = "rush4apps";
search.Show();
}
private void SendSms_Click(object sender, RoutedEventArgs e)
{
SmsComposeTask sms = new SmsComposeTask();
sms.Body = "Windows Phone 7 - отличная платформа!";
sms.Show();
}
private void WebBrowse_Click(object sender, RoutedEventArgs e)
{
WebBrowserTask web = new WebBrowserTask();
web.Uri = new Uri("https://msdn.com/ru-ru/");
web.Show();
}</code></pre>
Мы добавили кнопок по количеству демонстрируемых задач загрузки и в обработчике соответствующей кнопки вызываем интерфейс задачи загрузки. Некоторые из задач загрузки будут работать только на реальном устройстве. Обработчик с закомментированным кодом требуют вашего вмешательства перед тем, как их можно будет раскомментировать и запустить.
Соберите и запустите приложение (F5), посмотрите, как работают задачи запуска.
В качестве самостоятельного упражнения попробуйте добавить кнопки и дописать код для оставшихся задач запуска.
Задачи выбора (choosers)
Для того, чтобы использовать любую из задач выбора разработчику необходимо выполнить следующие шаги:
- Создать экземпляр класса задачи запуска.
- Добавить обработчик события Completed.
- Установить свойства полученного объекта.
- Вызвать метод Show объекта.
- Получить данные от задачи выбора в обработчике события Completed.
Разработчику доступны следующие задачи выбора:
Задача выбора |
Краткое описание |
AddressChooserTask |
Запускает приложение Contacts. Используется, чтобы получить адрес контакта, выбранного пользователем. |
CameraCaptureTask |
Запускает приложение Camera. Используется, чтобы дать возможность пользователю сделать фотографию из вашего приложения. |
EmailAddressChooserTask |
Запускает приложение Contacts. Используется, чтобы получить e-mail адрес контакта, выбранного пользователем. |
GameInviteTask |
Отображает экран приглашения в многопользовательскую сессию игры. |
PhoneNumberChooserTask |
Запускает приложение Contacts. Используется, чтобы получить телефон контакта, выбранного пользователем. |
PhotoChooserTask |
Запускает приложение PhotoChooser. Используется, чтобы дать возможность пользователю выбрать картинку. |
SaveContactTask |
|
SaveEmailAddressTask |
Запускает приложение Contacts. Используется, чтобы сохранить e-mail адрес в новый или существующий контакт. |
SavePhoneNumberTask |
Запускает приложение Contacts. Используется, чтобы сохранить номер телефона в новый или существующий контакт. |
SaveRingtoneTask |
Позволяет пользователю сохранить аудиофайл как системный рингтон. |
Создайте новый проект из шаблона Windows Phone Application, как мы это уже делали в первой части и назовите его ExploreChoosers. Обратите внимание, что весь код, для простоты, будем вставлять в страницу MainPage.xaml внутрь элемента Grid:
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid>
Добавьте код в XAML файл, чтобы он выглядел следующим образом:
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<Button Width="190" Height="75" Name="Camera" Content="Камера" Click="Camera_Click"/>
<Button Width="190" Height="75" Name="Email" Content="EMail" Click="Email_Click"/>
<Button Width="190" Height="75" Name="Phone" Content="Телефон" Click="Phone_Click"/>
<Button Width="190" Height="75" Name="ChoosePhoto" Content="Фото" Click="ChoosePhoto_Click"/>
<Button Width="190" Height="75" Name="SaveEMail" Content="Сохр. EMail" Click="SaveEMail_Click"/>
<Button Width="190" Height="75" Name="SavePhone" Content="Сохр. тел." Click="SavePhone_Click"/>
</StackPanel>
</Grid>
Добавьте в блок using следующий модуль.
using Microsoft.Phone.Tasks;
Сразу после конструктора MainPage добавьте следующий код:
private void Camera_Click(object sender, RoutedEventArgs e)
{
CameraCaptureTask camera = new CameraCaptureTask();
camera.Completed += new EventHandler<PhotoResult>(camera_Completed);
camera.Show();
}
void camera_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
MessageBox.Show("Имя файла:" + e.OriginalFileName);
}
private void Email_Click(object sender, RoutedEventArgs e)
{
EmailAddressChooserTask email = new EmailAddressChooserTask();
email.Completed += new EventHandler<EmailResult>(email_Completed);
email.Show();
}
void email_Completed(object sender, EmailResult e)
{
if (e.TaskResult == TaskResult.OK)
MessageBox.Show(e.Email);
}
private void Phone_Click(object sender, RoutedEventArgs e)
{
PhoneNumberChooserTask phone = new PhoneNumberChooserTask();
phone.Completed += new EventHandler<PhoneNumberResult>(phone_Completed);
phone.Show();
}
void phone_Completed(object sender, PhoneNumberResult e)
{
if (e.TaskResult == TaskResult.OK)
MessageBox.Show(e.PhoneNumber);
}
private void ChoosePhoto_Click(object sender, RoutedEventArgs e)
{
PhotoChooserTask photo = new PhotoChooserTask();
photo.Completed += new EventHandler<PhotoResult>(photo_Completed);
photo.Show();
}
void photo_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
MessageBox.Show(e.OriginalFileName);
}
private void SaveEMail_Click(object sender, RoutedEventArgs e)
{
SaveEmailAddressTask saveEmail = new SaveEmailAddressTask();
saveEmail.Completed += new EventHandler<TaskEventArgs>(saveEmail_Completed);
saveEmail.Email = "rush4apps@microsoft.com";
saveEmail.Show();
}
void saveEmail_Completed(object sender, TaskEventArgs e)
{
if (e.TaskResult == TaskResult.OK)
MessageBox.Show("EMail сохранен!");
}
private void SavePhone_Click(object sender, RoutedEventArgs e)
{
SavePhoneNumberTask savePhone = new SavePhoneNumberTask();
savePhone.Completed += new EventHandler<TaskEventArgs>(savePhone_Completed);
savePhone.PhoneNumber = "+7 495 555 5555";
savePhone.Show();
}
void savePhone_Completed(object sender, TaskEventArgs e)
{
if (e.TaskResult == TaskResult.OK)
MessageBox.Show("Номер сохранен!");
}
Мы добавили кнопок по количеству демонсрируемых задач выбора и в обработчике соответствующей кнопки регистририруем обработчик события Completed и вызываем интерфейс задачи выбора.
Соберите и запустите приложение (F5), посмотрите, как работают задачи выбора.
В качестве самостоятельного упражнения попробуйте добавить кнопки и дописать код для оставшихся задач выбора.
Элемент управления Map
Чтобы познакомиться с элементом управления Map, давайте создадим новый проект из шаблона Windows Phone Application, как мы это уже делали в первой части и назовём его ExploreMapControl.
После того, как создадите проект, посмотрите, на какие библиотеки он ссылается:
Разверните Toolbox, если он свёрнут, и перетяните элемент управления Map в дизайнер интерфейса приложения
Обратите внимание, что теперь проект ссылается на Microsoft.Phone.Controls.Map:
Двойным щелчком перейдем к странице MainPage.xaml и посмотрим, что изменилось в XAML коде.
Добавился элемент управления Map из пространства имён my:
<my:Map Height="50" HorizontalAlignment="Left" Margin="201,198,0,0" Name="map1" VerticalAlignment="Top" Width="100" />
Посмотрев на заголовок XAML документа можно увидеть, что это на пространство имён:
xmlns:my="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps"
Давайте заменим my на map, чтобы название пространства имён соответствовало его содержанию:
xmlns:map="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps"
и
<map:Map Height="50" HorizontalAlignment="Left" Margin="201,198,0,0" Name="map1" VerticalAlignment="Top" Width="100" />
Отредактируем XAML код элемента управления Map или воспользуемся панелью Properites так, чтобы элемент занимал большую часть свободного пространства и переименуем элемент в MyMap:
<map:Map Name="MyMap"/>
Запустите приложение (F5) и посмотрите, как выглядит элемент управления во время исполнения.
Обратили внимание на белый баннер в центре экрана, который говорит, что у нас неправильные авторизационные данные? Это потому что этот элемент управления использует сервис карт от Bing и для его использования требуется регистрация. Зарегистрироваться и получить ключ можно на портале Bing Maps: http://www.bingmapsportal.com/
В завершение регистрации разработчик получает строковый ключ, который надо указать в свойстве CredentialsProvider элмента управления, также его можно вынести в ресурсы или данные.
Добавим простые элементы управления картой: уменьшение/увеличение масштаба, смена режима отображения карты:
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<map:Map Name="MyMap">
<Button Name="ZoomIn" Content="+" HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="60" Width="60" Margin="-100,0,0,-5" Click="ZoomIn_Click" FontWeight="Bold" Padding="0,-9,0,0"/>
<Button Name="ZoomOut" Content="-" HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="60" Width="60" Margin="100,0,0,-5" Click="ZoomOut_Click" FontWeight="Bold" Padding="0,-9,0,0" />
<Button Name="LayoutChange" Content="L" HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="60" Width="60" Margin="0,0,0,-5" FontWeight="Bold" Padding="0,-9,0,0" Click="LayoutChange_Click"/>
</map:Map>
</Grid>
И обработаем эти события в коде приложения:
private void ZoomIn_Click(object sender, RoutedEventArgs e)
{
MyMap.ZoomLevel += 1;
}
private void ZoomOut_Click(object sender, RoutedEventArgs e)
{
MyMap.ZoomLevel -= 1;
}
private void LayoutChange_Click(object sender, RoutedEventArgs e)
{
if (MyMap.Mode is RoadMode)
{
MyMap.Mode = new AerialMode(true);
}
else
{
MyMap.Mode = new RoadMode();
}
}
Не забудьте добавить в блок using следующую директиву:
using Microsoft.Phone.Controls.Maps;
Запустите приложение (F5) и проверьте, что наши элементы управления работают, как предполагается.
В соответствии с Metro-дизайном панель с кнопками внизу окна приложения мы должны были бы оформить в виде Application Bar, только в целях упрощения примера мы используем более простой вариант. В качестве самостоятельного упражнения можете попробовать убрать кнопки, раскоментировать пример кода Application Bar в XAML файле и переделать приложение в соответствии со стилем Metro.
Элемент управления WebBrowser
Чтобы познакомиться с элементом управления Map, давайте создадим новый проект из шаблона Windows Phone Application, как мы это уже делали в первой части и назовём его ExploreWebControl.
После того, как создадите проект, посмотрите, на какие библиотеки он ссылается:
Разверните Toolbox, если он свёрнут, и перетяните элемент управления WebBrowser в дизайнер интерфейса приложения
Обратите внимание, что никаких дополнительных ссылок не добавилось:
Двойным щелчком перейдем к странице MainPage.xaml и посмотрим, что изменилось в XAML коде.
<phone:WebBrowser HorizontalAlignment="Left" Margin="174,169,0,0" Name="webBrowser1" VerticalAlignment="Top" />
Используется пространство имён phone, которое было добавлено в шаблон по умолчанию:
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
Оно содержит корневой элемент нашего XAML файла – элемент управления страницу приложения:
<phone:PhoneApplicationPage
x:Class="ExploreWebControl.MainPage"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
Отредактируем XAML код элемента управления WebBrowser или воспользуемся панелью Properites так, чтобы элемент занимал большую часть свободного пространства и переименуем элемент в MyBrowser, а также добавим прямо в XAML файл определение свойства Source, которое указывает элементу управления, откуда брать HTML для рендеренга. В качестве примера страницы я используют заглавную страницу русского MSDN:
<phone:WebBrowser Name="MyBrowser" Source="https://msdn.com/ru-ru/"/>
Запустите приложение (F5) и посмотрите, как выглядит элемент управления во время исполнения.
Сделаем теперь свой простой браузер: добавим строку ввода и кнопку Go, а также небольшой код для передачи URL браузеру и запуску навигации.
XAML код:
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBox Name="Url" InputScope="URL" Width="380"/>
<Button Name="Go" Width="82" Content="Go" Click="Go_Click"/>
</StackPanel>
<phone:WebBrowser Name="MyBrowser" Source="https://msdn.com/ru-ru/" Height="530"/>
</StackPanel>
</Grid>
Обработчик события нажатия кнопки:
private void Go_Click(object sender, RoutedEventArgs e)
{
try
{
Uri url = new Uri(Url.Text);
MyBrowser.Navigate(url);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Запустите приложение (F5) и проверьте, что оно работает и даже выводит сообщение об ошибке, при вводе неправильного URL.
Акселерометр
От программных возможностей платформы доступных разработчику давайте перейдем к аппаратным.
Давайте откроем ранее созданное приложение ExploreMapControl и добавим в него возможности акселерометра.
Для работы с акселерометром к проекту надо подключить библиотеку Microsoft.Devices.Sensors. Для этого в Solution Explorer правым щелчком мыши по папке Refernce вызовите контекстное меню, выберите Add Reference и добавьте Microsoft.Devices.Sensors. Далее, в блок using добавим следующую директиву:
using Microsoft.Devices.Sensors;
Теперь мы готовы работать с акселерометром.
Сделаем простое приложение, которое при покачивании телефона выполняло масштабирование карты. При отклонении от себя масштаб будет увеличиваться, а при отклонении телефона на себя – уменьшаться.
Добавим глобальную переменную в класс представляющую акселерометр:
private Accelerometer myAccel;
В конструктор класса добавим инициализацию акселерометра, обработчик изменения его состояний и стартуем акселерометр:
myAccel = new Accelerometer();
myAccel.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<AccelerometerReading>>(myAccel_CurrentValueChanged);
myAccel.Start();
Новый обработчик событий использует класс Vector3 из библиотеки Microsoft.Xna.Framework. Добавим в проект ссылку на библиотеку Microsoft.Xna.Framework, также как для Microsoft.Devices.Sensors, а также в блок using директиву:
using Microsoft.Xna.Framework;
Для того, чтобы реализовать тот функционал, который нам необходим, нужно хранить текущее (предыдущее состояние) акселерометра в классе. Добавим переменную в класс:
private Vector3 currentValues;
Теперь можно перейти к описанию логики обработчика состояния акселерометра:
void myAccel_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
{
if (myAccel.IsDataValid)
{
float deltaZ = (currentValues - e.SensorReading.Acceleration).Z;
float Z = e.SensorReading.Acceleration.Z;
currentValues = e.SensorReading.Acceleration;
if (Z < 0 && deltaZ > 0)
{
//увеличиваем масштаб
}
if (Z > 0 && deltaZ < 0)
{
//уменьшаем масштаб
}
}
}
Мы собираемся изменять состояние пользовательского интерфейса из потока акселерометра. Напрямую это невозможно. Функция обновления должна вызываться спциальным образом через объект Dispatcher:
Dispatcher.BeginInvoke
Создадим два обработчика в классе:
private void HandleZoomIn()
{
MyMap.ZoomLevel += 1;
}
private void HandleZoomOut()
{
MyMap.ZoomLevel -= 1;
}
И добавим соответствующие вызовы через Dispatcher:
Dispatcher.BeginInvoke(() => HandleZoomIn());
и
Dispatcher.BeginInvoke(() => HandleZoomOut());
Результирующий класс будет выглядеть следующим образом:
private Accelerometer myAccel;
private Vector3 currentValues;
// Constructor
public MainPage()
{
InitializeComponent();
myAccel = new Accelerometer();
myAccel.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<AccelerometerReading>>(myAccel_CurrentValueChanged);
myAccel.Start();
currentValues = myAccel.CurrentValue.Acceleration;
}
void myAccel_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
{
if (myAccel.IsDataValid)
{
float deltaZ = (currentValues - e.SensorReading.Acceleration).Z;
float Z = e.SensorReading.Acceleration.Z;
currentValues = e.SensorReading.Acceleration;
if (Z < 0 && deltaZ > 0)
{
Dispatcher.BeginInvoke(() => HandleZoomIn());
}
if (Z > 0 && deltaZ < 0)
{
Dispatcher.BeginInvoke(() => HandleZoomOut());
}
}
}
private void HandleZoomIn()
{
MyMap.ZoomLevel += 1;
}
private void HandleZoomOut()
{
MyMap.ZoomLevel -= 1;
}
private void ZoomIn_Click(object sender, RoutedEventArgs e)
{
MyMap.ZoomLevel += 1;
}
private void ZoomOut_Click(object sender, RoutedEventArgs e)
{
MyMap.ZoomLevel -= 1;
}
private void LayoutChange_Click(object sender, RoutedEventArgs e)
{
if (MyMap.Mode is RoadMode)
{
MyMap.Mode = new AerialMode(true);
}
else
{
MyMap.Mode = new RoadMode();
}
}
Запустите приложение (F5) и проверьте, что оно работает, как ожидается. Воспользуйтесь возможностями эмулятора, который поддерживает эмуляцию акселерометра.
Геолокационные данные
Наконец перейдём к геолокационным сервисам, доступным на телефоне. Сервис предоставляет информацию, используя комбинацию информации получаемой от Wi-Fi, сотовой связи и данных от GPS приёмника.
Давайте откроем ранее созданное приложение ExploreMapControl и добавим в него возможности предоставляемые сервисами геолокации.
Для начала, добавим в блок using следующую директиву:
using System.Device.Location;
Теперь мы готовы работать с сервисами локаций/местоположения.
Сначала напишем простое дополнение к нашей программе, которое будет центрировать карту в соответствии с гелолокационными данными, полученными от сервисов.
Добавим в класс определение переменной типа GeoCoordinateWatcher, которая позволит нам инициализировать сервисы геолокации и полчать от них данные.
private GeoCoordinateWatcher myGeoWatcher;
В конструктор класса, сразу же после кода относящегося к акселерометру добавим код инициализации и регистрации на события изменения статуса сервисов (они могут быть недоступны, могут быть не готовы и т.д.) и события изменения положения.
yGeoWatcher = new GeoCoordinateWatcher();
myGeoWatcher.MovementThreshold = 100.0f;
myGeoWatcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(myGeoWatcher_StatusChanged);
myGeoWatcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(myGeoWatcher_PositionChanged);
Хорошее приложение должно правильно обрабатывать статусы геосервисов, т.к. они не всегда могут выдавать данные и могут тратить достаточно большое время на инициализацию. Для начала мы просто оставим обработчик пустым, так как тестировать приложением мы будем на эмуляторе, и там эти проблемы отсутствуют.
Также правильнее будет поместить запуск сервиса геолокации в отдельный поток, чтобы не тормозить загрузку приложения, в нашем первом варианте приложения, с учётом использования эмулятора мы пока будем запускать сервис прямо в конструкторе класса:
myGeoWatcher.TryStart(false, TimeSpan.FromSeconds(60));
Если Visual Studio автоматически сгенерировала нам обработчики событий StatusChanged и PositionChanged, закомментируйте или сотрите код в этих методах, вызывающий исключение NotImplemented:
throw new NotImplementedException();
В обработчик события PositionChangedдобавьте код, центрирующий карту при изменении позиции:
void myGeoWatcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
MyMap.Center = e.Position.Location;
}
Запустите приложение (F5) и воспользуйтесь возможностями эмулятора по эмуляции геолкационных данных, чтобы проверить работу программы. Увеличьте масштаб так, чтобы убедиться, что позиционирование происходи правильно.
Следующим шагом, улучшения нашей программы может стать запуск сервисов в другом потоке, добавление строки статуса геолокационных данных, а также создание на карте точки, отмечающей наше местоположение.
Для использования потоков, добавим в блок using следующую директиву:
using System.Threading;
В конструкторе до запуска сервисов добавим код:
new Thread(startMyGeoWotcher).Start();
После этого создадим функцию, не принимающую и не возвращающую значений, с именем startMyGeoWotcher и перенесём в неё код запуска сервисов:
void startMyGeoWotcher()
{
myGeoWatcher.TryStart(false, TimeSpan.FromSeconds(60));
}
Теперь добавим элемент управление TextBlock для отображения статуса сервисов геолокации
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<TextBlock Name="GeoStatus" HorizontalAlignment="Center" VerticalAlignment="Top" Text="Geo Status .." />
<map:Map Name="MyMap" Height="580">
<Button Name="ZoomIn" Content="+" HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="60" Width="60" Margin="-100,0,0,-5" Click="ZoomIn_Click" FontWeight="Bold" Padding="0,-9,0,0"/>
<Button Name="ZoomOut" Content="-" HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="60" Width="60" Margin="100,0,0,-5" Click="ZoomOut_Click" FontWeight="Bold" Padding="0,-9,0,0" />
<Button Name="LayoutChange" Content="L" HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="60" Width="60" Margin="0,0,0,-5" FontWeight="Bold" Padding="0,-9,0,0" Click="LayoutChange_Click"/>
</map:Map>
</StackPanel>
</Grid>
И допишем вывод статусов в обработчик StatusChanged:
void myGeoWatcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
{
switch (e.Status)
{
case GeoPositionStatus.Disabled:
if (myGeoWatcher.Permission == GeoPositionPermission.Denied)
{
GeoStatus.Text = "Сервис выключен";
}
else
{
GeoStatus.Text = "На этом устройстве сервис недоступен";
}
break;
case GeoPositionStatus.Initializing:
GeoStatus.Text = "Сервис инициализируется";
break;
case GeoPositionStatus.NoData:
GeoStatus.Text = "Данные о месположении недоступны";
break;
case GeoPositionStatus.Ready:
GeoStatus.Text = "Данные о местоположении доступны";
break;
}
}
Наконец, в обработчик события изменения позиции добавим установку точки на карте.
В класс добавим переменную типа Pushpin:
private Pushpin myPushpin;
Создадим её в конструкторе класса:
myPushpin = new Pushpin();
В обработчике изменения позиции установим её на текущую позицию и добавим на карту, если её там нет:
myPushpin.Location = e.Position.Location;
if (!MyMap.Children.Contains(myPushpin)) MyMap.Children.Add(myPushpin);
Запустите приложение (F5) и воспользуйтесь возможностями эмулятора по эмуляции геолкационных данных, чтобы проверить работу программы. Увеличьте масштаб так, чтобы убедиться, что позиционирование и установка точки происходит правильно; также проверьте отображаемый статус сервисов геолокации.
Итоги и следующие шаги
Итак, мы познакомились с дополнительными возможностями платформы, которые может использовать разработчик мобильных приложений. Это были как программные возможности платформы, такие как задачи запуска и выбора, элементы управления Map и WebBrowser, так и аппаратные возможности работы с данными акселерометра и геолокации, доступные разработчику .
На следующем шаге мы познакомимся с возможностями платформы по локальному хранению данных и работе с веб.
Файлы для загрузки
Проект ExploreLaunchers
Проект ExploreChoosers
Проект ExploreMapControl
Проект ExploreMapControl с поддержкой геолокации
Проект ExploreMapControl с поддержкой акселерометра
Проект ExploreWebControl