Главная » Разработка для Windows Phone 7 » Панель приложения и элементы управления Windows Phone 7

0

Нет ничего удивительного в том, что Silverlight для Windows Phone поддерживает ряд стандартных элементов управления. Среди них ScrollBar (Полоса прокрутки) и Slider (Ползунок) для осуществления выбора из непрерывного диапазона значений, TextBox для ввода и редактирования текста, а также типовой набор кнопок, включая CheckBox (Флажок) для реализации опций вкл/выкл, RadioButton (Переключатель) для реализации группы взаимоисключающих опций и простой Button для запуска выполнения команд.

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

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

Этим механизмом является ApplicationBar (Панель приложения), который обычно называют app bar.

Значки ApplicationBar

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

ApplicationBar и связанные с ним классы (ApplicationBarIconButton (Кнопка панели приложения) и ApplicationBarMenuItem (Элемент меню панели приложения)) описаны в пространстве имен Microsoft.Phone.Shell. Эти классы наследуются от Object и существуют абсолютно отдельно от всей иерархии классов DependencyObject, UIElement и FrameworkElement, используемых при создании обычных приложений на Silverlight. Строго говоря, ApplicationBar не является частью дерева визуальных элементов страницы.

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

ApplicationBar может включать до четырех кнопок. Иногда их называют значками, потому что они всегда представлены в виде каких-то изображений. В качестве изображений, как правило, используются PNG-файлы; изображение должно быть квадратным со стороной 48 пикселов и преимущественно прозрачным. Но его видимая часть должна быть белой и

занимать квадрат со стороной 26 пикселов в центре основного изображения. Если вы установили Expressions Blend for Windows Phone, коллекцию растровых изображений можно найти в папке C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.0\Icons. Прежде чем создавать собственные изображения, внимательно изучите предлагаемые.

Предположим, мы нашли эти растровые изображения. Они хранятся в двух папках: light (черные изображения на белом фоне) и dark (белые изображения с прозрачным фоном). Несмотря на то что изображения из папки light выглядят в Windows Explorer лучше, в приложениях для телефона следует всегда использовать соответствующие файлы из папки dark.

Проект MoviePlayer включает элемент MediaElement для воспроизведения фильма и ApplicationBar со значками для воспроизведения, приостановки воспроизведения, перемотки назад и вперед.

В проекте Visual Studio, использующем ApplicationBar, должна быть отдельная папка для значков. Щелкните правой кнопкой мыши имя проекта и выберите в меню Add и New Folder. (Или выберите Add New Folder (Добавить новую папку) в меню Project.) Присвойте этой папке имя Images или нечто подобное. Щелкните правой кнопкой мыши имя папки, выберите Add и Existing Item и перейдите к папке dark с загруженными растровыми изображениями. Для MoviePlayer I были выбраны:

•         appbar.transport.ff.rest.png

•         appbar.transport.pause.rest.png

•         appbar.transport.play.rest.png

•         appbar.transport.rew.rest.png

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

А теперь обязательно для каждого из этих файлов из папки Images откройте страницу Properties (Свойства). (Возможно, придется щелкнуть имя файла правой кнопкой мыши и выбрать Properties из меню.) Задайте полю Build Action значение Content. ApplicationBar не сможет найти изображения, если в качестве Build Action будет задано Resource.

ApplicationBar не является частью стандартного Silverlight, поэтому описание пространства имен XML должно связывать пространство имен XML «shell» с пространством имен .NET Microsoft.Phone.Shell. Это делается автоматически в файле MainPage.xaml:

xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"

В конце файла MainPage.xaml представлен образец ApplicationBar. Можно раскомментировать и вносить изменения в него либо добавить собственный прямо перед закрывающим тегом phone:PhoneApplicationPage:

<phone:PhoneApplicationPage.ApplicationBar> <shell:ApplicationBar>

<shell:ApplicationBarIconButton

IconUri="Images/appbar.transport.rew.rest.png" Text="rewind" />

<shell:ApplicationBarIconButton

IconUri="Images/appbar.transport.play.rest.png" Text="play" />

<shell:ApplicationBarIconButton

IconUri="Images/appbar.transport.pause.rest.png"

Text="pause" />

<shell:ApplicationBarIconButton

IconUri="Images/appbar.transport.ff.rest.png" Text="to end" /> </shell:ApplicationBar> </phone:PhoneApplicationPage.ApplicationBar>

У ApplicationBar есть свойство Buttons (Кнопки), которое является свойством содержимого класса. В коллекции Buttons может быть не более четырех объектов ApplicationBarIconButton. Поля IconUri (URI значка) и Text являются обязательными! Текстовое описание должно быть коротким; все буквы преобразованы в строчные в целях удобства отображения.

Выполните сборку и развертывание приложения в том состоянии, в котором оно находится сейчас. На рисунке показано, как все это будет выглядеть на экране. (Я также удалил заголовок страницы.)

Будьте внимательны с этим свойством и не используйте значки, которые могут запутать пользователя при альбомном расположении экрана. Если в одном значке имеется горизонтальная черта, и в другом – вертикальная, это может сбить с толку и пользователя, и разработчика.

ApplicationBar можно описать в XAML. Чтобы его не было видно на экране раньше времени, задайте его свойству IsVisible значение false:

<shell:ApplicationBar IsVisible="False">

Потом значение этого свойства можно изменить в коде. Нет смысла описывать атрибут x:Name для организации доступа к ApplicationBar из кода. Это необъяснимо, но факт: ссылаться на объект ApplicationBar по имени в коде нельзя. Добраться к нему можно только через свойство ApplicationBar объекта MainPage:

this.ApplicationBar.IsVisible = true;

ApplicationBar также описывает свойства ForegroundColor (Цвет переднего плана) и BackgroundColor (Цвет фона), которые следует игнорировать. Цвета ApplicationBar будут меняться по умолчанию при изменении и соответственно выбранной цветовой схеме телефона.

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

Свойство Opacity по умолчанию имеет значение 1, т.е. фон ApplicationBar непрозрачный. Цвет фона определяет ресурс PhoneChromeBrush (Кисть визуального стиля телефона): очень темный серый для темной цветовой темы и очень светлый серый для светлой темы.

Когда свойство Opacity равно 1, ApplicationBar занимает область отображения отдельно от содержимого страницы. При любых других значениях Opacity содержимое страницы и ApplicationBar совместно используют общую область. ApplicationBar всегда располагается поверх всего остального содержимого. Когда Opacity принимает значение 0, фон ApplicationBar становится совершенно прозрачным, и под его значками можно видеть любое содержимое, оказавшееся в этой же области сетки для содержимого. В документации для Opacity рекомендуется использовать значения 1, 0,5 или 0.

Если в какой-то момент времени какой-то из значков теряет свою актуальность, для отражения этого в ApplicationBarIconButton предусмотрено свойство IsEnabled, которому можно задать значение false. Например, кнопки Play и Pause (Пауза) не должны быть активными одновременно. Рассмотрим, как можно деактивировать кнопку Pause при запуске:

<shell:ApplicationBarIconButton

IconUri="Images/appbar.transport.pause.rest.png"

Text="Pause"

IsEnabled="False" />

И вот как это выглядит на экране:

Эту кнопку можно активировать позже в коде, но, опять же, для этого не может использоваться x:Name. Это третья кнопка, следовательно, в коллекции Buttons она идет под индексом 2. Задать для нее свойство IsEnabled в коде можно следующим образом:

(this.ApplicationBar.Buttons[2] as ApplicationBarIconButton).IsEnabled = true;

Вероятно, одновременно с этим необходимо деактивировать кнопку Play:

(this.ApplicationBar.Buttons[1] as ApplicationBarIconButton).IsEnabled = false;

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

Также приложение должно знать, когда произошло нажатие активной кнопки пользователем . Зададим обработчик событий Click:

<shell:ApplicationBarIconButton

IconUri="Images/appbar.transport.play.rest.png" Text="Play"

Click="OnAppBarPlayClick" />

В файле выделенного кода для реализации обработчика используется делегат EventHandler (Обработчик событий):

void OnAppbarPlayClick(object sender, EventArgs args) {

}

Окончательный вариант ApplicationBar в проекте MoviePlayer выглядит следующим образом: Проект Silverlight: MoviePlayer Файл: MainPage.xaml (фрагмент)

<phone:PhoneApplicationPage.ApplicationBar> <shell:ApplicationBar x:Name="appbar"> <shell:ApplicationBarIconButton

x:Name="appbarRewindButton"

IconUri="Images/appbar.transport.rew.rest.png" Text="rewind" IsEnabled="False" Click="OnAppbarRewindClick" />

<shell:ApplicationBarIconButton

x:Name="appbarPlayButton"

IconUri="Images/appbar.transport.play.rest.png"

Text="play"

IsEnabled="False"

Click="OnAppbarPlayClick" />

<shell:ApplicationBarIconButton

x:Name="appbarPauseButton"

IconUri="Images/appbar.transport.pause.rest.png"

Text="pause"

IsEnabled="False"

Click="OnAppbarPauseClick" />

<shell:ApplicationBarIconButton x:Name="appbarEndButton"

IconUri="Images/appbar.transport.ff.rest.png" Text="to end" IsEnabled="False" Click="OnAppbarEndClick" /> </shell:ApplicationBar> </phone:PhoneApplicationPage.ApplicationBar>

Да, здесь всем кнопкам назначены атрибуты x:Name, но вскоре мы увидим, что они переопределены в коде.

Сетка для содержимого включает MediaElement для воспроизведения фильма и два элемента TextBlock для вывода сообщений о состоянии и ошибках:

Проект Silverlight: MoviePlayer Файл: MainPage.xaml (фрагмент)

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <MediaElement Name="mediaElement"

Source="http://www.charlespetzold.com/Media/Walrus.wmv" AutoPlay="False"

Media0pened="0nMediaElementMedia0pened" MediaFailed="0nMediaElementMediaFailed"

CurrentStateChanged="0nMediaElementCurrentStateChanged" />

<TextBlock Name="statusText"

HorizontalAlignment="Left" VerticalAlignment="Bottom" />

<TextBlock Name="errorText"

HorizontalAlignment="Right" VerticalAlignment="Bottom" TextWrapping="Wrap" />

</Grid>

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

В конструкторе MainPage всем ApplicationBarIconButton назначаются соответствующие атрибуты x:Name. Это делается для удобства создания ссылок на них в остальном классе:

Проект Silverlight: MoviePlayer Файл: MainPage.xaml.cs (фрагмент)

public MainPage() {

InitializeComponent();

// Переназначение имен, заданных в XAML-файле

appbarRewindButton = this.ApplicationBar.Buttons[0] as ApplicationBarIconButton; appbarPlayButton = this.ApplicationBar.Buttons[1] as ApplicationBarIconButton; appbarPauseButton = this.ApplicationBar.Buttons[2] as ApplicationBarIconButton; appbarEndButton = this.ApplicationBar.Buttons[3] as ApplicationBarIconButton;

}

Все четыре обработчика кнопок ApplicationBar занимают по одной строке кода:

Проект Silverlight: MoviePlayer Файл: MainPage.xaml.cs (фрагмент)

void 0nAppbarRewindClick(object sender, EventArgs args) mediaElement.Position = TimeSpan.Zero;

void 0nAppbarPlayClick(object sender, EventArgs args) mediaElement.Play();

void 0nAppbarPauseClick(object sender, EventArgs args) mediaElement.Pause();

void 0nAppbarEndClick(object sender, EventArgs args)

mediaElement.Position = mediaElement.NaturalDuration.TimeSpan;

Самой запутанной частью приложения для воспроизведения фильмов является активация и деактивация кнопок. Поскольку основной целью данной программы является демонстрация использования ApplicationBar, я применил здесь очень простой подход: кнопки Rewind (Назад) и End (Вперед) активируются, когда файл мультимедиа открыт, кнопки Play и Pause активируются на основании значения свойства CurrentState (Текущее состояние) элемента MediaElement:

Проект Silverlight: MoviePlayer Файл: MainPage.xaml.cs (фрагмент)

void OnMediaElementMediaFailed(object sender, ExceptionRoutedEventArgs args) {

errorText.Text = args.ErrorException.Message;

}

void OnMediaElementMediaOpened(object sender, RoutedEventArgs args) {

appbarRewindButton.IsEnabled = true; appbarEndButton.IsEnabled = true;

}

void OnMediaElementCurrentStateChanged(object sender, RoutedEventArgs args) {

statusText.Text = mediaElement.CurrentState.ToString();

if (mediaElement.CurrentState == MediaElementState.Stopped || mediaElement.CurrentState == MediaElementState.Paused)

{

appbarPlayButton.IsEnabled = true; appbarPauseButton.IsEnabled = false;

}

else if (mediaElement.CurrentState == MediaElementState.Playing) {

appbarPlayButton.IsEnabled = false; appbarPauseButton.IsEnabled = true;

}

}

Источник: Чарльз Петзольд, Программируем Windows Phone 7, Microsoft Press, © 2011.

По теме:

  • Комментарии