Разработка компьютерных игр для Windows Phone 7 с использованием технологий Silverlight и XNA

Введение в Silverlight, знакомство с проектом, первое приложение

Разбить на страницы
Показывать лекцию целиком

Цель работы: Освоить структуру стандартного Silverlight-проекта

28.1. Создание Silverlight-проекта

Выше мы обсуждали особенности применения Silverlight в разработке для Windows Phone. Основное направление использования этой технологии заключается в построении бизнес-приложений. Однако, возможности Silverlight позволяют создавать игры, и, кроме того, с недавних пор можно комбинировать в одном приложении и возможности Silverlight (например, для создания пользовательского интерфейса), и возможности XNA (преимущественно – для вывода графики). Таким образом, разработчик игр должен быть, по крайней мере, знать основы Silverlight.

Это позволит ему не "изобретать велосипед" на XNA, при возникновении ситуации, когда, например, игра нуждается в использовании элементов управления, таких, как, например, список. Реализация элементов управления, аналогичных тем, которые доступны в Silverlight-приложении, с помощью методов XNA возможна, но потребует определенных усилий. И заниматься такой разработкой есть смысл лишь в том случае, если разработчик знаком с Silverlight, с XNA и совершенно точно понимает, что такая разработка ему действительно нужна.

Начнём изучение основ разработки игр на Silverlight с рассмотрения типовых шаблонов проекта, доступных при создании нового проекта на Silverlight. При создании нового приложения, с выбором набора шаблонов Silverlight for Windows Phone, нам доступны несколько вариантов, рис. 28.1 Рассмотрим некоторые из них.

(рис 28.1) Выбор типа нового проекта на Silverlight

Приложение Windows Phone – каркас приложения для Windows Phone, без элементов управления. В сформированном приложении будет доступна одна страница, с которой и начинается разработка. Приложение может иметь множество страниц, мы можем настраивать навигацию между ними, работу с данными, расположенными на страницах. Пример Silverlight-страницы вы можете видеть на рис. 28.2

(рис 28.2) Silverlight-страница

Панорамное приложение Windows Phone – каркас приложения с использованием элемента управления Panorama. С помощью этого элемента управления часто организуют приложения на Windows Phone. Его можно представить как широкий, шириной в несколько экранов, "лист", на разных видимых областях которого расположены элементы управления, отвечающие за различные функции программы, за различные настройки и так далее. Обычно в верхней части элемента управления Panorama расположена некая надпись, например, название программы, которая проходит по нескольким видимым экранам элемента управления.

Для перемещения по отдельным страницам панорамы достаточно "листать" их в нужном направлении. Фон панорамы обычно представляет собой какое-либо изображение, скорость прокрутки которого отличается от скорости прокрутки остального контента. Например, подобным образом в Windows Phone организован хаб Marketplace – верхнюю часть экрана занимает надпись Marketplace, отдельные экраны представляют собой (если говорить о смартфонах Nokia) – экран Эксклюзивы Nokia, Программы, Игры, на фоне выводится одно большое изображение, проходящее по всем экранам. Хаб Marketplace вы можете видеть на рис. 28.3.

(рис 28.3) Интерфейс, основанный на элементе управления Panorama

Сводное приложение Windows Phone – каркас приложения, использующего элемент управления Pivot. Этот элемент управления похож на элемент управления Panorama, однако, он позволяет организовать интерфейс, напоминающий окно с несколькими вкладками, если говорить о привычных способах построения настольных Windows-интерфейсов. У каждой вкладки есть свой заголовок, общий заголовок представлен обычной, не "растянутой" надписью, перемещение между соседними вкладками осуществляется либо "перелистыванием" экранов, либо – нажатием на доступные заголовки экранов. Таким образом, например, организованы настройки Windows Phone, рис. 28.4.

(рис 28.4) Интерфейс, основанный на элементе управления Pivot

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

Сейчас мы создадим приложение на основе шаблона Приложение на Windows Phone, назовем проект P21_1. Перед созданием нового проекта, система задаст вопрос, знакомый вам по XNA-проектам, который касается целевой версии ОС Windows Phone. Здесь, рис. 28.5, доступны ОС Windows Phone 7.0. и ОС Windows Phone 7.1. Выберем версию 7.1.

(рис 28.5) Выбор целевой платформы Windows Phone для приложения

28.2. Особенности среды разработки

На рис. 28.6 вы можете видеть окно Visual Studio 2010 после создания нового Silverlight-приложения.

(рис 28.6) Окно Visual Studio после создания нового Silverlight-приложения

Если сравнивать это окно с тем, к чему мы привыкли, работая с XNA-проектами, можно заметить здесь множество особенностей. Так, во-первых, разработка для Silverlight ведется как в визуальном режиме, так и путём редактирования программного кода.

Для обеспечения визуальных средств разработки в окне есть макет страницы, выведенный в виде, приближенном к реальному. В окне просмотра можно видеть изображение страницы, над которой мы работаем. Это изображение может соответствовать тому, что мы получим на устройстве, а может и нет – всё дело в настройках устройства.

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

Далее, в окне среды разработки имеется панель Элементы управления. Для добавления элементов управления на страницы, достаточно выделить мышью нужный элемент и либо перетащить его на страницу, либо обвести прямоугольником выделения ту область на странице, в которой планируется разместить этот элемент.

После размещения, параметры элемента можно настраивать как интерактивно (используя маркеры изменения размера в окне, перетаскивая элемент в нужное место, редактируя свойства элемента в окне Свойства), так и редактируя программный код. Добавление элемента управления на страницу в интерактивном режиме, в сущности, означает лишь автоматическую правку соответствующего кода.

На рис. 28.7 вы можете видеть окно редактора сразу после добавления в окно нового элемента управления Button (Кнопка).

(рис 28.7) Результат добавления на страницу нового элемента управления

Кроме того, здесь же можно наблюдать описание кнопки в файле MainPage.xaml, которое было добавлено в него автоматически.

Напишем простое приложение на Silverlight, которое предоставляет пользователю поле для ввода имени и кнопку с надписью "Нажми меня". Пользователь вводит в поле своё имя, нажимает на кнопку и видит всплывающее окно с надписью "Здравствуйте, Имя_Пользователя!". Кнопка у нас уже есть, изменим её свойство Content в окне Свойства на "Нажми меня".

Добавим на страницу новый элемент управления TextBox (Текстовое поле), введем в его свойство Text (этот текст будет отображаться в поле по умолчанию) текст: "Введите ваше имя".

Теперь, в коде файла MainPage.xaml, отредактируем заголовок приложения и заголовок страницы. Это можно сделать, изменив свойство Text для элементов управления TextBox (они используются для вывода надписей) ApplicationTitle (заголовок приложения) и PageTitle (заголовок страницы). Для ApplicationTitle зададим текст "МОЕ ПЕРВОЕ ПРИЛОЖЕНИЕ", для PageTitle "приветствие". То есть, сначала мы имели блок кода, представленный в листинге 28.1

        <!--TitlePanel содержит имя приложения и заголовок страницы-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="МОЕ ПРИЛОЖЕНИЕ" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="имя страницы" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

После его редактирования имеем блок кода, представленный в листинге 28.2

<!--TitlePanel содержит имя приложения и заголовок страницы-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="МОЕ ПЕРВОЕ ПРИЛОЖЕНИЕ" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="приветствие" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>
        

Того же эффекта можно было добиться, выделив соответствующие надписи в окне визуальной настройки страницы и отредактировав их свойства Text в окне Свойства. Переместим поля так, чтобы текстовое поле находилось выше кнопки.

Теперь выполним двойной щелчок по кнопке. В редакторе автоматически будет открыт файл MainPage.xaml.cs, в нём будет сформирован обработчик события Click для кнопки, то есть, тот код, который будет выполняться при нажатии на кнопку.

У кнопок, да и у других элементов управления, есть множество событий, реакцию программы на которые можно настраивать, для этого можно воспользоваться закладкой События окна Свойства, выделив соответствующий элемент управления.

Для задания обработчика достаточно ввести в поле, соответствующее событию, имя процедуры, в которой планируется обрабатывать это событие. Естественно, настройка реакции элементов управления на события так же отражается на коде файла MainPage.xaml. Фактически, в XAML-коде указано имя метода, который является обработчиком конкретного события, в CS-коде находится сам обработчик, код которого можно редактировать

Реализовывать заявленную функциональность программы мы будем именно в этом обработчике. Кроме того, мы хотели бы, чтобы при выборе поля текст из него автоматически удалялся бы. Для этого зададим обработчик события текстового поля GotFocus (Получение фокуса ввода). Выделим поле, откроем закладку События окна Свойства и введем в поле задания обработчика события для GotFocus текст textBox1_GotFocus, рис. 28.8. Это приведет к созданию нового обработчика события GotFocus для текстового поля.

(рис 28.8) Создание обработчика события GotFocus для текстового поля

Итак, в файле MainPage.xaml.cs мы имеем пару пустых обработчиков событий, листинг 28.3.

   private void button1_Click(object sender, RoutedEventArgs e)
        {
            
        }


        private void textBox1_GotFocus(object sender, RoutedEventArgs e)
        {
            
        }

Вот как будут выглядеть эти обработчики после ввода в них соответствующего кода, листинг 28.4.

  private void button1_Click(object sender, RoutedEventArgs e)
        {
            //Формируем всплывающее окно с сообщением
            MessageBox.Show("Здравствуйте, " + textBox1.Text + "!", 
                "Приветствие", 
                MessageBoxButton.OK);
        }


        private void textBox1_GotFocus(object sender, RoutedEventArgs e)
        {
            //Очищаем поле при получении им фокуса ввода
            textBox1.Text = "";
        }

Здесь мы, при получении текстовым полем фокуса ввода очищаем его, присваивая его свойству Text пустую строку, а при нажатии на кнопку выводим окно сообщения с заголовком "Приветствие", с текстом "Здравствуйте, Имя_Пользователя!" и кнопкой ОК.

Вызов метода Show, в данном случае, это – вызов перегруженного варианта метода. В исходном варианте метод можно вызвать, передав ему лишь строку сообщения. Помимо кнопки ОК, отображение которой мы здесь задали явно, перечисление MessageBoxButton содержит еще значение OKCancel.

Выбор этого варианта позволяет вывести в окно сообщения кнопки ОК и Отмена. Кнопку, которую нажал пользователь, можно узнать, присвоив переменной типа MessageBoxResult результат выполнения метода Show.

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

(рис 28.9) Запуск проекта в эмуляторе

При прикосновении к текстовому полю, оно очищается, появляется экранная клавиатура, с помощью которой можно ввести имя пользователя, рис. 28.10.

(рис 28.10) Экранная клавиатура и заполнение поля

После того, как имя введено, для скрытия клавиатуры можно нажать на кнопку Назад (Back), или, так как в нашем случае клавиатура не скрывает кнопку, сразу нажать на кнопку Нажми меня. Это приведет к появлению окна сообщения, рис. 28.11.

(рис 28.11) Окно сообщения

Только что мы создали и испытали наше первое Silverlight-приложение. Теперь рассмотрим структуру проекта Silverlight-приложения, с отдельными элементами которой мы уже взаимодействовали.

28.3. Структура проекта Silverlight-приложения

На рис. 28.12 вы можете видеть окно Обозреватель решений для нашего проекта.

(рис 28.12) Обозреватель решений проекта P21_1

Некоторые из элементов этого окна вам уже знакомы по XNA-проектам. Напомним о значении этих, знакомых файлов и подробнее остановимся на элементах, специфичных для Silverlight-приложения.

  • AppManifest.xml – файл манифеста, нужен для создания пакета приложения
  • AssemblyInfo.cs – метаданные сборки.
  • WMAppManifest.cs – настройки приложения, специфичные для Windows Phone
  • App.xaml – параметры, данные, настройки уровня приложения.
  • App.xaml.cs – файл кода, связанный с файлом App.xaml (code-behind). Обработка событий и ошибок уровня приложения.
  • MainPage.xaml – главная страница приложения, описание разметки страницы на XAML.
  • MainPage.xaml.cs – код страницы. Именно здесь содержится программный код, имеющий отношение к главной странице.
  • ApplicationIcon.png – изображение ярлыка программы, которое используется для её отображения в общем списке программ.
  • Background.png – изображение ярлыка программы, которое используется в том случае, если программа закреплена на рабочем столе устройства.
  • SplashScreenImage.jpg – сплэш-скрин (стартовый экран) приложения – изображение, которое отображается при старте программы.
  • Рассмотрим файл App.xaml нашего приложения, его вы можете видеть в листинге 28.5.

    <Application 
        x:Class="P21_1.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"       
        xmlns:x="http://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">
    
        <!--Ресурсы приложения-->
        <Application.Resources>
        </Application.Resources>
    
        <Application.ApplicationLifetimeObjects>
            <!--Обязательный объект, обрабатывающий события времени жизни приложения-->
            <shell:PhoneApplicationService 
                Launching="Application_Launching" Closing="Application_Closing" 
                Activated="Application_Activated" Deactivated="Application_Deactivated"/>
        </Application.ApplicationLifetimeObjects>
    
    </Application>

    В этом файле определяются четыре обработчика событий, код которых находится в файле App.xaml.cs. Это – события, которые позволяют управлять жизненным циклом приложения. Событие Launching происходит при запуске приложения, Closing – при выходе приложения, Deactivated – при деактивации приложения (например, если пользователь нажимает кнопку Домой при работе в приложении), Activated – при возврату к приложению после деактивации. Кроме того, здесь могут быть определены ресурсы приложения.

    Посмотрим код файла App.xaml.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    using Microsoft.Phone.Shell;
    
    namespace P21_1
    {
        public partial class App : Application
        {
            /// <summary>
            /// Обеспечивает быстрый доступ к корневому кадру приложения телефона.
            /// </summary>
            /// <returns>Корневой кадр приложения телефона.</returns>
            public PhoneApplicationFrame RootFrame { get; private set; }
    
            /// <summary>
            /// Конструктор объекта приложения.
            /// </summary>
            public App()
            {
                // Глобальный обработчик неперехваченных исключений. 
                UnhandledException += Application_UnhandledException;
    
                // Стандартная инициализация Silverlight
                InitializeComponent();
    
                // Инициализация телефона
                InitializePhoneApplication();
    
                // Отображение сведений о профиле графики во время отладки.
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    // Отображение текущих счетчиков частоты смены кадров.
                    Application.Current.Host.Settings.EnableFrameRateCounter = true;
    
                    // Отображение областей приложения, перерисовываемых в каждом кадре.
                    //Application.Current.Host.Settings.EnableRedrawRegions = true;
    
                    // Включение режима визуализации анализа нерабочего кода 
                    // для отображения областей страницы, переданных в GPU, с цветным наложением.
                    //Application.Current.Host.Settings.EnableCacheVisualization = true;
    
                    // Отключите обнаружение простоя приложения, установив для свойства UserIdleDetectionMode
                    // объекта PhoneApplicationService приложения значение Disabled.
                    // Внимание! Используйте только в режиме отладки. 
                    // Приложение, в котором отключено обнаружение бездействия пользователя, 
                    // будет продолжать работать
                    // и потреблять энергию батареи, когда телефон не будет использоваться.
                    PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
                }
    
            }
    
            // Код для выполнения при запуске приложения (например, из меню "Пуск")
            // Этот код не будет выполняться при повторной активации приложения
            private void Application_Launching(object sender, LaunchingEventArgs e)
            {
            }
    
            // Код для выполнения при активации приложения (переводится в основной режим)
            // Этот код не будет выполняться при первом запуске приложения
            private void Application_Activated(object sender, ActivatedEventArgs e)
            {
            }
    
            // Код для выполнения при деактивации приложения (отправляется в фоновый режим)
            // Этот код не будет выполняться при закрытии приложения
            private void Application_Deactivated(object sender, DeactivatedEventArgs e)
            {
            }
    
            // Код для выполнения при закрытии приложения (например, при нажатии пользователем кнопки "Назад")
            // Этот код не будет выполняться при деактивации приложения
            private void Application_Closing(object sender, ClosingEventArgs e)
            {
            }
    
            // Код для выполнения в случае ошибки навигации
            private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    // Ошибка навигации; перейти в отладчик
                    System.Diagnostics.Debugger.Break();
                }
            }
    
            // Код для выполнения на необработанных исключениях
            private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    // Произошло необработанное исключение; перейти в отладчик
                    System.Diagnostics.Debugger.Break();
                }
            }
    
            #region Инициализация приложения телефона
    
            // Избегайте двойной инициализации
            private bool phoneApplicationInitialized = false;
    
            // Не добавляйте в этот метод дополнительный код
            private void InitializePhoneApplication()
            {
                if (phoneApplicationInitialized)
                    return;
    
                // Создайте кадр, но не задавайте для него значение RootVisual; это позволит
                // экрану-заставке оставаться активным, пока приложение не будет готово для визуализации.
                RootFrame = new PhoneApplicationFrame();
                RootFrame.Navigated += CompleteInitializePhoneApplication;
    
                // Обработка сбоев навигации
                RootFrame.NavigationFailed += RootFrame_NavigationFailed;
    
                // Убедитесь, что инициализация не выполняется повторно
                phoneApplicationInitialized = true;
            }
    
            // Не добавляйте в этот метод дополнительный код
            private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
            {
                // Задайте корневой визуальный элемент для визуализации приложения
                if (RootVisual != RootFrame)
                    RootVisual = RootFrame;
    
                // Удалите этот обработчик, т.к. он больше не нужен
                RootFrame.Navigated -= CompleteInitializePhoneApplication;
            }
    
            #endregion
        }

    Здесь, по умолчанию, заданы обработчики событий уровня приложения, часть из них мы обсуждали выше (к тому же, файл хорошо прокомментирован, что облегчает работу с ним). Здесь же выполняется инициализация приложения, настроен показ отладочной информации. Обратите внимание на объект RootFrame типа PhoneApplicationFrame. Этот объект является основой пользовательского интерфейса приложения, отвечает за расположение страниц на экране, за ориентацию экрана. Он напоминает веб-браузер, который отображает страницы приложения.

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

    Рассмотрим файл MainPage.xaml

    <phone:PhoneApplicationPage 
        x:Class="P21_1.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://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="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://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">
    
        <!--LayoutRoot представляет корневую сетку, где размещается все содержимое страницы-->
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    
            <!--TitlePanel содержит имя приложения и заголовок страницы-->
            <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
                <TextBlock x:Name="ApplicationTitle" Text="МОЕ ПЕРВОЕ ПРИЛОЖЕНИЕ" Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock x:Name="PageTitle" Text="приветствие" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
            </StackPanel>
    
            <!--ContentPanel — поместите здесь дополнительное содержимое-->
            <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
                <Button Content="Нажми меня" Height="72" HorizontalAlignment="Left" Margin="121,210,0,0" 
    Name="button1" VerticalAlignment="Top" Width="220" Click="button1_Click" />
                <TextBox Height="73" HorizontalAlignment="Left" Margin="61,60,0,0" Name="textBox1" Text="Введите ваше имя" 
    VerticalAlignment="Top" Width="351" GotFocus="textBox1_GotFocus" />
            </Grid>
        </Grid>
     
        <!--Пример кода, иллюстрирующий использование ApplicationBar-->
        <!--<phone:PhoneApplicationPage.ApplicationBar>
            <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
                <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Кнопка 1"/>
                <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Кнопка 2"/>
                <shell:ApplicationBar.MenuItems>
                    <shell:ApplicationBarMenuItem Text="Элемент меню 1"/>
                    <shell:ApplicationBarMenuItem Text="Элемент меню 2"/>
                </shell:ApplicationBar.MenuItems>
            </shell:ApplicationBar>
        </phone:PhoneApplicationPage.ApplicationBar>-->
    
    </phone:PhoneApplicationPage>

    Файл хранит описание главной страницы приложения, по умолчанию в данном случае для страницы применяется портретная ориентация, которая не будет меняться при повороте дисплея, элементы страницы огранизованы в соответствии с сеткой (элемент управления Grid), в ячейках которой расположена стек-панель, выводящая название приложения и заголовок страницы. Кроме того, при разработке нашего приложения мы добавили сюда текстовое поле (TextBox) и кнопку (Button). Их описания расположены в области контент-панели (ContentPanel). Описания, кроме параметров отображения элементов, задают и обработчики событий элементов, которые можно найти в файле MainPage.xaml.cs, листинг 21.8.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    namespace P21_1
    {
        public partial class MainPage : PhoneApplicationPage
        {
            // Конструктор
            public MainPage()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                //Формируем всплывающее окно с сообщением
                MessageBox.Show("Здравствуйте, " + textBox1.Text + "!", 
                    "Приветствие", 
                    MessageBoxButton.OK);
            }
    
    
            private void textBox1_GotFocus(object sender, RoutedEventArgs e)
            {
                //Очищаем поле при получении им фокуса ввода
                textBox1.Text = "";
            }
    
        }
    }

    По умолчанию файл содержит лишь конструктор, вызывающий метод InitializeComponent(), код метода расположен в автоматически генерируемом системой файле MainPage.g.i.cs, посмотреть его можно, если вызвать контекстное меню для строки InitializeComponent() и выбрать там команду Перейти к определению. Файл не предназначен для ручного редактирования, однако, его анализ может помочь в решении проблем. Проблемы эти могут быть вызваны ошибками в соответствующем XAML-файле. Похожий файл (App.g.i.cs) формируется и для App.xaml.

    28.4. Выводы

    В этой лабораторной работе мы поговорили о различных видах стандартных проектах Silverlight-приложений, разобрали состав проекта одностраничного приложения и написали учебное приложение, демонстрирующее работу с элементами управления и обращение с кодом, связанным с данными элементами управления

    28.5. Задание

    Создайте Silverlight-приложения, основанные на различных шаблонах (кроме шаблона, совмещающего XNA и Silverlight, ему будет посвящена отдельная лабораторная работа). Изучите получившиеся проекты. Подумайте, как с помощью этих шаблонов можно организовать интерфейсы различных приложений и игр.

    28.6. Дополнительные материалы

    К данной лабораторной работе прилагается видеоурок

    и демонстрационный проект.

    Страницы:

    Цель работы: Освоить структуру стандартного Silverlight-проекта

    28.1. Создание Silverlight-проекта

    Выше мы обсуждали особенности применения Silverlight в разработке для Windows Phone. Основное направление использования этой технологии заключается в построении бизнес-приложений. Однако, возможности Silverlight позволяют создавать игры, и, кроме того, с недавних пор можно комбинировать в одном приложении и возможности Silverlight (например, для создания пользовательского интерфейса), и возможности XNA (преимущественно – для вывода графики). Таким образом, разработчик игр должен быть, по крайней мере, знать основы Silverlight.

    Это позволит ему не "изобретать велосипед" на XNA, при возникновении ситуации, когда, например, игра нуждается в использовании элементов управления, таких, как, например, список. Реализация элементов управления, аналогичных тем, которые доступны в Silverlight-приложении, с помощью методов XNA возможна, но потребует определенных усилий. И заниматься такой разработкой есть смысл лишь в том случае, если разработчик знаком с Silverlight, с XNA и совершенно точно понимает, что такая разработка ему действительно нужна.

    Начнём изучение основ разработки игр на Silverlight с рассмотрения типовых шаблонов проекта, доступных при создании нового проекта на Silverlight. При создании нового приложения, с выбором набора шаблонов Silverlight for Windows Phone, нам доступны несколько вариантов, рис. 28.1 Рассмотрим некоторые из них.

    (рис 28.1) Выбор типа нового проекта на Silverlight

    Приложение Windows Phone – каркас приложения для Windows Phone, без элементов управления. В сформированном приложении будет доступна одна страница, с которой и начинается разработка. Приложение может иметь множество страниц, мы можем настраивать навигацию между ними, работу с данными, расположенными на страницах. Пример Silverlight-страницы вы можете видеть на рис. 28.2

    (рис 28.2) Silverlight-страница

    Панорамное приложение Windows Phone – каркас приложения с использованием элемента управления Panorama. С помощью этого элемента управления часто организуют приложения на Windows Phone. Его можно представить как широкий, шириной в несколько экранов, "лист", на разных видимых областях которого расположены элементы управления, отвечающие за различные функции программы, за различные настройки и так далее. Обычно в верхней части элемента управления Panorama расположена некая надпись, например, название программы, которая проходит по нескольким видимым экранам элемента управления.

    Для перемещения по отдельным страницам панорамы достаточно "листать" их в нужном направлении. Фон панорамы обычно представляет собой какое-либо изображение, скорость прокрутки которого отличается от скорости прокрутки остального контента. Например, подобным образом в Windows Phone организован хаб Marketplace – верхнюю часть экрана занимает надпись Marketplace, отдельные экраны представляют собой (если говорить о смартфонах Nokia) – экран Эксклюзивы Nokia, Программы, Игры, на фоне выводится одно большое изображение, проходящее по всем экранам. Хаб Marketplace вы можете видеть на рис. 28.3.

    (рис 28.3) Интерфейс, основанный на элементе управления Panorama

    Сводное приложение Windows Phone – каркас приложения, использующего элемент управления Pivot. Этот элемент управления похож на элемент управления Panorama, однако, он позволяет организовать интерфейс, напоминающий окно с несколькими вкладками, если говорить о привычных способах построения настольных Windows-интерфейсов. У каждой вкладки есть свой заголовок, общий заголовок представлен обычной, не "растянутой" надписью, перемещение между соседними вкладками осуществляется либо "перелистыванием" экранов, либо – нажатием на доступные заголовки экранов. Таким образом, например, организованы настройки Windows Phone, рис. 28.4.

    (рис 28.4) Интерфейс, основанный на элементе управления Pivot

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

    Сейчас мы создадим приложение на основе шаблона Приложение на Windows Phone, назовем проект P21_1. Перед созданием нового проекта, система задаст вопрос, знакомый вам по XNA-проектам, который касается целевой версии ОС Windows Phone. Здесь, рис. 28.5, доступны ОС Windows Phone 7.0. и ОС Windows Phone 7.1. Выберем версию 7.1.

    (рис 28.5) Выбор целевой платформы Windows Phone для приложения

    28.2. Особенности среды разработки

    На рис. 28.6 вы можете видеть окно Visual Studio 2010 после создания нового Silverlight-приложения.

    (рис 28.6) Окно Visual Studio после создания нового Silverlight-приложения

    Если сравнивать это окно с тем, к чему мы привыкли, работая с XNA-проектами, можно заметить здесь множество особенностей. Так, во-первых, разработка для Silverlight ведется как в визуальном режиме, так и путём редактирования программного кода.

    Для обеспечения визуальных средств разработки в окне есть макет страницы, выведенный в виде, приближенном к реальному. В окне просмотра можно видеть изображение страницы, над которой мы работаем. Это изображение может соответствовать тому, что мы получим на устройстве, а может и нет – всё дело в настройках устройства.

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

    Далее, в окне среды разработки имеется панель Элементы управления. Для добавления элементов управления на страницы, достаточно выделить мышью нужный элемент и либо перетащить его на страницу, либо обвести прямоугольником выделения ту область на странице, в которой планируется разместить этот элемент.

    После размещения, параметры элемента можно настраивать как интерактивно (используя маркеры изменения размера в окне, перетаскивая элемент в нужное место, редактируя свойства элемента в окне Свойства), так и редактируя программный код. Добавление элемента управления на страницу в интерактивном режиме, в сущности, означает лишь автоматическую правку соответствующего кода.

    На рис. 28.7 вы можете видеть окно редактора сразу после добавления в окно нового элемента управления Button (Кнопка).

    (рис 28.7) Результат добавления на страницу нового элемента управления

    Кроме того, здесь же можно наблюдать описание кнопки в файле MainPage.xaml, которое было добавлено в него автоматически.

    Напишем простое приложение на Silverlight, которое предоставляет пользователю поле для ввода имени и кнопку с надписью "Нажми меня". Пользователь вводит в поле своё имя, нажимает на кнопку и видит всплывающее окно с надписью "Здравствуйте, Имя_Пользователя!". Кнопка у нас уже есть, изменим её свойство Content в окне Свойства на "Нажми меня".

    Добавим на страницу новый элемент управления TextBox (Текстовое поле), введем в его свойство Text (этот текст будет отображаться в поле по умолчанию) текст: "Введите ваше имя".

    Теперь, в коде файла MainPage.xaml, отредактируем заголовок приложения и заголовок страницы. Это можно сделать, изменив свойство Text для элементов управления TextBox (они используются для вывода надписей) ApplicationTitle (заголовок приложения) и PageTitle (заголовок страницы). Для ApplicationTitle зададим текст "МОЕ ПЕРВОЕ ПРИЛОЖЕНИЕ", для PageTitle "приветствие". То есть, сначала мы имели блок кода, представленный в листинге 28.1

            <!--TitlePanel содержит имя приложения и заголовок страницы-->
            <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
                <TextBlock x:Name="ApplicationTitle" Text="МОЕ ПРИЛОЖЕНИЕ" Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock x:Name="PageTitle" Text="имя страницы" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
            </StackPanel>
    

    После его редактирования имеем блок кода, представленный в листинге 28.2

    <!--TitlePanel содержит имя приложения и заголовок страницы-->
            <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
                <TextBlock x:Name="ApplicationTitle" Text="МОЕ ПЕРВОЕ ПРИЛОЖЕНИЕ" Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock x:Name="PageTitle" Text="приветствие" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
            </StackPanel>
            

    Того же эффекта можно было добиться, выделив соответствующие надписи в окне визуальной настройки страницы и отредактировав их свойства Text в окне Свойства. Переместим поля так, чтобы текстовое поле находилось выше кнопки.

    Теперь выполним двойной щелчок по кнопке. В редакторе автоматически будет открыт файл MainPage.xaml.cs, в нём будет сформирован обработчик события Click для кнопки, то есть, тот код, который будет выполняться при нажатии на кнопку.

    У кнопок, да и у других элементов управления, есть множество событий, реакцию программы на которые можно настраивать, для этого можно воспользоваться закладкой События окна Свойства, выделив соответствующий элемент управления.

    Для задания обработчика достаточно ввести в поле, соответствующее событию, имя процедуры, в которой планируется обрабатывать это событие. Естественно, настройка реакции элементов управления на события так же отражается на коде файла MainPage.xaml. Фактически, в XAML-коде указано имя метода, который является обработчиком конкретного события, в CS-коде находится сам обработчик, код которого можно редактировать

    Реализовывать заявленную функциональность программы мы будем именно в этом обработчике. Кроме того, мы хотели бы, чтобы при выборе поля текст из него автоматически удалялся бы. Для этого зададим обработчик события текстового поля GotFocus (Получение фокуса ввода). Выделим поле, откроем закладку События окна Свойства и введем в поле задания обработчика события для GotFocus текст textBox1_GotFocus, рис. 28.8. Это приведет к созданию нового обработчика события GotFocus для текстового поля.

    (рис 28.8) Создание обработчика события GotFocus для текстового поля

    Итак, в файле MainPage.xaml.cs мы имеем пару пустых обработчиков событий, листинг 28.3.

       private void button1_Click(object sender, RoutedEventArgs e)
            {
                
            }
    
    
            private void textBox1_GotFocus(object sender, RoutedEventArgs e)
            {
                
            }

    Вот как будут выглядеть эти обработчики после ввода в них соответствующего кода, листинг 28.4.

      private void button1_Click(object sender, RoutedEventArgs e)
            {
                //Формируем всплывающее окно с сообщением
                MessageBox.Show("Здравствуйте, " + textBox1.Text + "!", 
                    "Приветствие", 
                    MessageBoxButton.OK);
            }
    
    
            private void textBox1_GotFocus(object sender, RoutedEventArgs e)
            {
                //Очищаем поле при получении им фокуса ввода
                textBox1.Text = "";
            }

    Здесь мы, при получении текстовым полем фокуса ввода очищаем его, присваивая его свойству Text пустую строку, а при нажатии на кнопку выводим окно сообщения с заголовком "Приветствие", с текстом "Здравствуйте, Имя_Пользователя!" и кнопкой ОК.

    Вызов метода Show, в данном случае, это – вызов перегруженного варианта метода. В исходном варианте метод можно вызвать, передав ему лишь строку сообщения. Помимо кнопки ОК, отображение которой мы здесь задали явно, перечисление MessageBoxButton содержит еще значение OKCancel.

    Выбор этого варианта позволяет вывести в окно сообщения кнопки ОК и Отмена. Кнопку, которую нажал пользователь, можно узнать, присвоив переменной типа MessageBoxResult результат выполнения метода Show.

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

    (рис 28.9) Запуск проекта в эмуляторе

    При прикосновении к текстовому полю, оно очищается, появляется экранная клавиатура, с помощью которой можно ввести имя пользователя, рис. 28.10.

    (рис 28.10) Экранная клавиатура и заполнение поля

    После того, как имя введено, для скрытия клавиатуры можно нажать на кнопку Назад (Back), или, так как в нашем случае клавиатура не скрывает кнопку, сразу нажать на кнопку Нажми меня. Это приведет к появлению окна сообщения, рис. 28.11.

    (рис 28.11) Окно сообщения

    Только что мы создали и испытали наше первое Silverlight-приложение. Теперь рассмотрим структуру проекта Silverlight-приложения, с отдельными элементами которой мы уже взаимодействовали.

    28.3. Структура проекта Silverlight-приложения

    На рис. 28.12 вы можете видеть окно Обозреватель решений для нашего проекта.

    (рис 28.12) Обозреватель решений проекта P21_1

    Некоторые из элементов этого окна вам уже знакомы по XNA-проектам. Напомним о значении этих, знакомых файлов и подробнее остановимся на элементах, специфичных для Silverlight-приложения.

  • AppManifest.xml – файл манифеста, нужен для создания пакета приложения
  • AssemblyInfo.cs – метаданные сборки.
  • WMAppManifest.cs – настройки приложения, специфичные для Windows Phone
  • App.xaml – параметры, данные, настройки уровня приложения.
  • App.xaml.cs – файл кода, связанный с файлом App.xaml (code-behind). Обработка событий и ошибок уровня приложения.
  • MainPage.xaml – главная страница приложения, описание разметки страницы на XAML.
  • MainPage.xaml.cs – код страницы. Именно здесь содержится программный код, имеющий отношение к главной странице.
  • ApplicationIcon.png – изображение ярлыка программы, которое используется для её отображения в общем списке программ.
  • Background.png – изображение ярлыка программы, которое используется в том случае, если программа закреплена на рабочем столе устройства.
  • SplashScreenImage.jpg – сплэш-скрин (стартовый экран) приложения – изображение, которое отображается при старте программы.
  • Рассмотрим файл App.xaml нашего приложения, его вы можете видеть в листинге 28.5.

    <Application 
        x:Class="P21_1.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"       
        xmlns:x="http://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">
    
        <!--Ресурсы приложения-->
        <Application.Resources>
        </Application.Resources>
    
        <Application.ApplicationLifetimeObjects>
            <!--Обязательный объект, обрабатывающий события времени жизни приложения-->
            <shell:PhoneApplicationService 
                Launching="Application_Launching" Closing="Application_Closing" 
                Activated="Application_Activated" Deactivated="Application_Deactivated"/>
        </Application.ApplicationLifetimeObjects>
    
    </Application>

    В этом файле определяются четыре обработчика событий, код которых находится в файле App.xaml.cs. Это – события, которые позволяют управлять жизненным циклом приложения. Событие Launching происходит при запуске приложения, Closing – при выходе приложения, Deactivated – при деактивации приложения (например, если пользователь нажимает кнопку Домой при работе в приложении), Activated – при возврату к приложению после деактивации. Кроме того, здесь могут быть определены ресурсы приложения.

    Посмотрим код файла App.xaml.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    using Microsoft.Phone.Shell;
    
    namespace P21_1
    {
        public partial class App : Application
        {
            /// <summary>
            /// Обеспечивает быстрый доступ к корневому кадру приложения телефона.
            /// </summary>
            /// <returns>Корневой кадр приложения телефона.</returns>
            public PhoneApplicationFrame RootFrame { get; private set; }
    
            /// <summary>
            /// Конструктор объекта приложения.
            /// </summary>
            public App()
            {
                // Глобальный обработчик неперехваченных исключений. 
                UnhandledException += Application_UnhandledException;
    
                // Стандартная инициализация Silverlight
                InitializeComponent();
    
                // Инициализация телефона
                InitializePhoneApplication();
    
                // Отображение сведений о профиле графики во время отладки.
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    // Отображение текущих счетчиков частоты смены кадров.
                    Application.Current.Host.Settings.EnableFrameRateCounter = true;
    
                    // Отображение областей приложения, перерисовываемых в каждом кадре.
                    //Application.Current.Host.Settings.EnableRedrawRegions = true;
    
                    // Включение режима визуализации анализа нерабочего кода 
                    // для отображения областей страницы, переданных в GPU, с цветным наложением.
                    //Application.Current.Host.Settings.EnableCacheVisualization = true;
    
                    // Отключите обнаружение простоя приложения, установив для свойства UserIdleDetectionMode
                    // объекта PhoneApplicationService приложения значение Disabled.
                    // Внимание! Используйте только в режиме отладки. 
                    // Приложение, в котором отключено обнаружение бездействия пользователя, 
                    // будет продолжать работать
                    // и потреблять энергию батареи, когда телефон не будет использоваться.
                    PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
                }
    
            }
    
            // Код для выполнения при запуске приложения (например, из меню "Пуск")
            // Этот код не будет выполняться при повторной активации приложения
            private void Application_Launching(object sender, LaunchingEventArgs e)
            {
            }
    
            // Код для выполнения при активации приложения (переводится в основной режим)
            // Этот код не будет выполняться при первом запуске приложения
            private void Application_Activated(object sender, ActivatedEventArgs e)
            {
            }
    
            // Код для выполнения при деактивации приложения (отправляется в фоновый режим)
            // Этот код не будет выполняться при закрытии приложения
            private void Application_Deactivated(object sender, DeactivatedEventArgs e)
            {
            }
    
            // Код для выполнения при закрытии приложения (например, при нажатии пользователем кнопки "Назад")
            // Этот код не будет выполняться при деактивации приложения
            private void Application_Closing(object sender, ClosingEventArgs e)
            {
            }
    
            // Код для выполнения в случае ошибки навигации
            private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    // Ошибка навигации; перейти в отладчик
                    System.Diagnostics.Debugger.Break();
                }
            }
    
            // Код для выполнения на необработанных исключениях
            private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    // Произошло необработанное исключение; перейти в отладчик
                    System.Diagnostics.Debugger.Break();
                }
            }
    
            #region Инициализация приложения телефона
    
            // Избегайте двойной инициализации
            private bool phoneApplicationInitialized = false;
    
            // Не добавляйте в этот метод дополнительный код
            private void InitializePhoneApplication()
            {
                if (phoneApplicationInitialized)
                    return;
    
                // Создайте кадр, но не задавайте для него значение RootVisual; это позволит
                // экрану-заставке оставаться активным, пока приложение не будет готово для визуализации.
                RootFrame = new PhoneApplicationFrame();
                RootFrame.Navigated += CompleteInitializePhoneApplication;
    
                // Обработка сбоев навигации
                RootFrame.NavigationFailed += RootFrame_NavigationFailed;
    
                // Убедитесь, что инициализация не выполняется повторно
                phoneApplicationInitialized = true;
            }
    
            // Не добавляйте в этот метод дополнительный код
            private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
            {
                // Задайте корневой визуальный элемент для визуализации приложения
                if (RootVisual != RootFrame)
                    RootVisual = RootFrame;
    
                // Удалите этот обработчик, т.к. он больше не нужен
                RootFrame.Navigated -= CompleteInitializePhoneApplication;
            }
    
            #endregion
        }

    Здесь, по умолчанию, заданы обработчики событий уровня приложения, часть из них мы обсуждали выше (к тому же, файл хорошо прокомментирован, что облегчает работу с ним). Здесь же выполняется инициализация приложения, настроен показ отладочной информации. Обратите внимание на объект RootFrame типа PhoneApplicationFrame. Этот объект является основой пользовательского интерфейса приложения, отвечает за расположение страниц на экране, за ориентацию экрана. Он напоминает веб-браузер, который отображает страницы приложения.

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

    Рассмотрим файл MainPage.xaml

    <phone:PhoneApplicationPage 
        x:Class="P21_1.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://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="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://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">
    
        <!--LayoutRoot представляет корневую сетку, где размещается все содержимое страницы-->
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    
            <!--TitlePanel содержит имя приложения и заголовок страницы-->
            <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
                <TextBlock x:Name="ApplicationTitle" Text="МОЕ ПЕРВОЕ ПРИЛОЖЕНИЕ" Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock x:Name="PageTitle" Text="приветствие" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
            </StackPanel>
    
            <!--ContentPanel — поместите здесь дополнительное содержимое-->
            <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
                <Button Content="Нажми меня" Height="72" HorizontalAlignment="Left" Margin="121,210,0,0" 
    Name="button1" VerticalAlignment="Top" Width="220" Click="button1_Click" />
                <TextBox Height="73" HorizontalAlignment="Left" Margin="61,60,0,0" Name="textBox1" Text="Введите ваше имя" 
    VerticalAlignment="Top" Width="351" GotFocus="textBox1_GotFocus" />
            </Grid>
        </Grid>
     
        <!--Пример кода, иллюстрирующий использование ApplicationBar-->
        <!--<phone:PhoneApplicationPage.ApplicationBar>
            <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
                <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Кнопка 1"/>
                <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Кнопка 2"/>
                <shell:ApplicationBar.MenuItems>
                    <shell:ApplicationBarMenuItem Text="Элемент меню 1"/>
                    <shell:ApplicationBarMenuItem Text="Элемент меню 2"/>
                </shell:ApplicationBar.MenuItems>
            </shell:ApplicationBar>
        </phone:PhoneApplicationPage.ApplicationBar>-->
    
    </phone:PhoneApplicationPage>

    Файл хранит описание главной страницы приложения, по умолчанию в данном случае для страницы применяется портретная ориентация, которая не будет меняться при повороте дисплея, элементы страницы огранизованы в соответствии с сеткой (элемент управления Grid), в ячейках которой расположена стек-панель, выводящая название приложения и заголовок страницы. Кроме того, при разработке нашего приложения мы добавили сюда текстовое поле (TextBox) и кнопку (Button). Их описания расположены в области контент-панели (ContentPanel). Описания, кроме параметров отображения элементов, задают и обработчики событий элементов, которые можно найти в файле MainPage.xaml.cs, листинг 21.8.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    namespace P21_1
    {
        public partial class MainPage : PhoneApplicationPage
        {
            // Конструктор
            public MainPage()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                //Формируем всплывающее окно с сообщением
                MessageBox.Show("Здравствуйте, " + textBox1.Text + "!", 
                    "Приветствие", 
                    MessageBoxButton.OK);
            }
    
    
            private void textBox1_GotFocus(object sender, RoutedEventArgs e)
            {
                //Очищаем поле при получении им фокуса ввода
                textBox1.Text = "";
            }
    
        }
    }

    По умолчанию файл содержит лишь конструктор, вызывающий метод InitializeComponent(), код метода расположен в автоматически генерируемом системой файле MainPage.g.i.cs, посмотреть его можно, если вызвать контекстное меню для строки InitializeComponent() и выбрать там команду Перейти к определению. Файл не предназначен для ручного редактирования, однако, его анализ может помочь в решении проблем. Проблемы эти могут быть вызваны ошибками в соответствующем XAML-файле. Похожий файл (App.g.i.cs) формируется и для App.xaml.

    28.4. Выводы

    В этой лабораторной работе мы поговорили о различных видах стандартных проектах Silverlight-приложений, разобрали состав проекта одностраничного приложения и написали учебное приложение, демонстрирующее работу с элементами управления и обращение с кодом, связанным с данными элементами управления

    28.5. Задание

    Создайте Silverlight-приложения, основанные на различных шаблонах (кроме шаблона, совмещающего XNA и Silverlight, ему будет посвящена отдельная лабораторная работа). Изучите получившиеся проекты. Подумайте, как с помощью этих шаблонов можно организовать интерфейсы различных приложений и игр.

    28.6. Дополнительные материалы

    К данной лабораторной работе прилагается видеоурок

    и демонстрационный проект.

    Вернуться к учебному плану