Эта статья содержит примеры кода, подсвеченные с помощью JS SyntaxHighlighter, который почему-то не отрабатывает в Google Reader, а возможно и в других RSS ридерах. Чтобы нормально увидеть код, вам придется перейти в блог. Извините за неудобство.
Недавно я делал code session на встрече харьковской UNETA на тему создания картографического приложения для Windows Phone 7. По моим субъективным ощущениям все прошло неплохо, слушатели помогали мне в написании кода, активно задавали вопросы и поправляли меня, когда я где-нибудь лажал :), а также стойко терпели технические проблемы, связанные со взаимной нелюбовью моего ноутбука и местного проектора, за что им отдельное спасибо. Так как тема программирования под Windows Phone сейчас интересна многим людям, хотелось бы также выложить материалы этого code session в блог.
Этой статьей я начинаю серию, посвященную созданию простенького картографического приложения на Silverlight с использованием Bing Maps. В процессе написания приложения я иногда буду уходить в теорию, чтобы пояснить те или иные детали. Итак, приступим.
Требования
Прежде чем начинать писать приложение, необходимо определиться что мы, собственно говоря, хотим написать. Наше приложение будет отображать текущее местонахождение человека, а также показывать положение различных объектов вокруг него: кафе, гостиниц, магазинов, банков, туристических мест, ночных клубов и прочего добра. По идее, оно должно помогать людям ориентироваться в малознакомом или даже родном городе. Если собрать все требования в кучку, то мы получим следующий набор функций приложения:
- отображение карты
- определение текущего местоположения, центрирование карты
- отображение различных объектов вокруг текущего местоположения
- отображение деталей объекта при клике на нем
- фильтрация объектов по типам
При этом мы попытаемся реализовать приложение в более-менее правильном стиле, с использованием паттерна MVVM.
Начнем с создания проекта и отображения простой карты.
Создание проекта
Перед тем, как начать программировать для Windows Phone 7, вам нужно убедиться, что у вас есть вся инфраструктура:
- Visual Studio 2010 (есть бесплатная версия VS2010 Express for Windows Phone)
- Windows Phone Developer Tools (Silverlight for Windows Phone, эмулятор, библиотеки и т.д.)
- Bing Maps Silverlight control for Windows Phone
- (опционально) XNA Game Studio 4.0
- (опционально) Expression Blend (есть бесплатная версия Blend for Windows Phone)
Все это добро бесплатно и его можно скачать с сайта http://create.msdn.com/en-us/home/getting_started. После того, как установите основной пакет, не забудьте также установить October 2010 update to the Windows Phone Developer Tools.
Вообще, конечно, радует, что Microsoft решила сделать все инструменты для разработки WP7 приложений бесплатными. Но это не подарок на Новый год, а простой маркетинг: нужно привлекать программистов на новую платформу, чтобы догнать уходящий поезд, на котором дружно едут iOS и Android.
Немного о платформе разработки
Как вы уже догадались, писать мы будем на Silverlight. Только не на обычном Silverlight 4, а на т.н. Silverlight for Windows Phone. Эта версия SL отличается от своего настольного брата немного урезанными возможностями и оптимизированной производительностью. В общем-то производительность для телефона – это все, потому что по сравнению с native-приложениями у нас и сам .NET довольно прожорливый, и тем более Silverlight.
Кроме программирования бизнес-приложений (и в более редких случаях игр) на SL, у нас также есть возможность программировать игры (и в более редких случаях бизнес-приложения) на XNA. XNA – это платформа и набор инструментов для разработки игр для Windows, Xbox, Zune и вот теперь еще Windows Phone 7.
Поддержка XNA в Windows Phone – это очень полезная вещь, т.к. разработчики игр под Xbox теперь могут использовать привычные инструменты и модель разработки для программирования игр под мобильную платформу, а также с меньшими трудозатратами перенести существующие игры на WP7.
Отображение карты
Вернемся к практике. После установки необходимых дополнений в Visual Studio появятся новые типы проектов. Поэтому идем в File -> New -> Project и создаем Windows Phone Application проект.
Начнем мы с отображения карты. Здесь все просто. Сначала добавим в проект reference на сборку Microsoft.Phone.Controls.Maps. Затем добавим namespace для Bing Maps контрола, а также сам контрол в XAML главной страницы приложения, попутно заменив основной Grid на Canvas, чтобы нам было проще позиционировать элементы в будущем:
xmlns:maps="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps"
<!--LayoutRoot is the root grid where all page content is placed--> <Canvas x:Name="LayoutRoot"> <Grid Background="Transparent" Height="768" Width="480"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!--TitlePanel contains the name of the application and page title--> <TextBlock x:Name="ApplicationTitle" Grid.Row="0" Text="My Places" Style="{StaticResource PhoneTextNormalStyle}"/> <maps:Map Grid.Row="1" Name="mapPlace" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ScaleVisibility="Visible" ZoomBarVisibility="Visible" CopyrightVisibility="Collapsed"> <maps:Map.Mode> <maps:AerialMode ShouldDisplayLabels="True" /> </maps:Map.Mode> </maps:Map> </Grid> </Canvas>
Свойства контрола ScaleVisibility, ZoomBarVisibility и CopyrightVisibility определяют видимость соответствующих стандартных элементов карты. Надо отметить, что стандартный Zoom Bar располагается снизу (что не всегда удобно) + выглядит очень плохо, поэтому немного позже мы его улучшим.
Запустим приложение в эмуляторе. Как видите, приложение показывает карту:
Если присмотреться, то можно заметить, что посередине экрана белым шрифтом написан следующий текст:
Invalid Credentials. Sign up for for a developer account.
Этот текст обозначает, что нам нужно получить Bing Maps Developer Account и сообщить о нем контролу карты. Для этого идем на http://www.bingmapsportal.com/, логинимся туда при помощи Live ID (или сначала регистрируем его), и затем создаем ключ при помощи пункта меню Create or view keys.
Для того, чтобы карта заработала, достаточно установить свойство CredentialsProvider контрола:
CredentialsProvider="AoYOaLG9nor0LXJzvYrL18U8URccNTyacL-qfGUMBdvFseoLbF384hct4JxGVvI9"
Напомню, что ключ у вас должен быть свой. Это не важно для тестового проекта, но не уверен, что не будет проблем в случае публикации вашего приложения на MarketPlace.
Однако мы же пытаемся все делать правильно, используя паттерн MVVM, не так ли? Поэтому данный способ не совсем для нас. Этот ключ – данные, а данные должны связываться с View (представление, наша страница) через ViewModel (модель представления), специальный объект, содержащий весь набор данных, необходимых View для работы, а также логику представления. Выглядеть это должно где-то так:
Дополнительную информацию по паттерну MVVM и его примеры для Silverlight можно прочитать на страничке MSDN и в статье в MSDN Magazine.
Итак, нам нужно сделать ViewModel класс и как-то привязать его к View. Создадим в проекте папку ViewModel, в которой будут лежать все модели представления, а следом класс MapViewModel, который будет связываться с представлением нашей главной страницы). На данном этапе класс будет выглядеть следующим образом:
public class MapViewModel { private const string Id = "AoYOaLG9nor0LXJzvYrL18U8URccNTyacL-qfGUMBdvFseoLbF384hct4JxGVvI9"; private readonly CredentialsProvider credentialsProvider = new ApplicationIdCredentialsProvider(Id); public CredentialsProvider CredentialsProvider { get { return credentialsProvider; } } }
Как видите, наш ключ для Bing Maps прописан в нем как константа. Конечно, его можно было бы вынести и в какой-нибудь конфигурационный файл, но для нас это сейчас не принципиально.
Далее привязываем MapsViewModel к представлению в XAML файле страницы. Добавляем namespace:
xmlns:model="clr-namespace:WP7Test.ViewModel"
Говорим нашей View, что ее ViewModel будем класс MapsViewModel, установив свойство PhoneApplicationPage.Resources (перед началом тега Canvas):
<phone:PhoneApplicationPage.Resources> <model:MapViewModel x:Key="ViewModel" /> </phone:PhoneApplicationPage.Resources>
Устанавливаем свойство DataContext у Canvas:
<Canvas x:Name="LayoutRoot" DataContext="{StaticResource ViewModel}">
Теперь, когда ViewModel привязан к представлению, можно связать установить свойство CredentialsProvider контрола Map через стандартный data binding:
CredentialsProvider="{Binding ViewModel.CredentialsProvider}"
Вот и все. Запускаем, и видим, что наше приложение больше не показывает белую строчку.
В следующей части мы рассмотрим кастомизацию Zoom Bar.
Вся серия:
Часть 1. Введение
Часть 2. Масштабирование карты
Часть 3. Полные исходники