Задание
Создать приложение Windows Phone 7, запускающее фоновую службу, которая при активации меняет тайлы приложения.
Освоение
Описание
Создадим новый проект Silverlight for Windows Phone – Windows Phone Application. Разметка главной страницы будет состоять из 2 кнопок при нажатии на которые мы будем запускать и останавливать фоновую службу:
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<TextBlock Text="Служба для периодической смены тайлов приложения."
FontSize="26" Height="460" TextWrapping="Wrap" />
<Button Name="btnSvcStart" Content="Запустить службу"
Click="btnSvcStart_Click" />
<Button Name="btnSvcStop" Content="Остановить службу"
Click="btnSvcStop_Click" />
</StackPanel>
</Grid>
Добавим в решение (solution) новый проект Silverlight for Windows Phone – Windows Phone Scheduled Task Agent.
В наш основной проект добавим ссылку на проект службы: Add Reference… – Projects - <имя проекта службы>. Также добавим несколько изображений размера 173x173 (для тайлов). Назовем их, например, "Tile01.png", "Tile02.png", …, "Tile05.png". Установим для данных изображений свойство "Build Action" в "Content".
Примечание: тайлы – это изображения, отображающиеся на главной странице Windows Phone 7. Они могут иметь пояснительные надписи и обратную сторону – другое изображение, которое будет периодически появляться. Для того чтобы добавить тайл приложения на главную страницу, в списке приложений нажмите на ваше приложение и удерживайте. В появившемся контекстном меню выберете "pin to start" Рис. 5.1 :
(рис 5.1) Отображение тайла приложения на главной странице
В проекте службы в методе OnInvoke() будем задавать логику работы службы – смену изображения для тайла приложения. Для определения текущего номера будем пользоваться изолированным хранилищем (либо можно определять тайл случайным образом).
protected override void OnInvoke(ScheduledTask task)
{
//TODO: Add code to perform your task in background
int nTileNumber = 0;
if (IsIsolatedStorageExist())
{
string strTileNum = LoadFromIsolatedStorage();
nTileNumber = int.Parse(strTileNum);
}
const int MAX_TILE_NUMBER = 5;
nTileNumber++;
if (nTileNumber > MAX_TILE_NUMBER) nTileNumber = 1;
string strTileName = "/Tiles/Tile0" + nTileNumber.ToString() + ".png";
SetTile(strTileName);
SaveToIsolatedStorage(nTileNumber.ToString());
#if DEBUG
ScheduledActionService.LaunchForTest(task.Name, System.TimeSpan.FromSeconds(10));
#endif
NotifyComplete();
}
private void SetTile(string strPath)
{
ShellTile apptile = ShellTile.ActiveTiles.First();
StandardTileData appTileData = new StandardTileData();
appTileData.Title = "Служба";
appTileData.Count = 0;
appTileData.BackgroundImage = new Uri(strPath, UriKind.RelativeOrAbsolute);
apptile.Update(appTileData);
}
Для работы данного кода необходимо добавить следующие директивы:
using System; using System.Linq; using Microsoft.Phone.Shell;
Конструкция
#if DEBUG
ScheduledActionService.LaunchForTest(task.Name, System.TimeSpan.FromSeconds(10));
#endif
позволяет в отладочном режиме вызывать службу каждые 10 секунд.
Вернемся к основному проекту. Объявим в классе константу с именем службы:
private const string AGENT_NAME = "Agent_Wp7IUSLab22";
Для работы со службами добавим директиву:
using Microsoft.Phone.Scheduler;
При запуске службы сначала будем проверять, существует ли служба с таким именем (если существует – будем удалять), а затем будем запускать ее. При остановке будем удалять ее и очищать изолированное хранилище.
private void btnSvcStart_Click(object sender, RoutedEventArgs e)
{
//ищем службу
PeriodicTask myPeriodicTask = ScheduledActionService.Find(AGENT_NAME) as PeriodicTask;
//если нашли
if (myPeriodicTask != null)
{
try
{
//удаляем
ScheduledActionService.Remove(AGENT_NAME);
}
catch (Exception ex)
{
MessageBox.Show("Невозможно удалить ранее созданную службу: " + ex.Message);
}
}
//создаем службу
myPeriodicTask = new PeriodicTask(AGENT_NAME);
myPeriodicTask.Description = "Служба для периодической смены тайлов приложения.";
try
{
ScheduledActionService.Add(myPeriodicTask);
#if DEBUG
ScheduledActionService.LaunchForTest(AGENT_NAME, TimeSpan.FromSeconds(5));
#endif
MessageBox.Show("Служба запущена.");
}
catch (Exception ex)
{
MessageBox.Show("Невозможно создать службу: " + ex.Message);
}
}
private void btnSvcStop_Click(object sender, RoutedEventArgs e)
{
//ищем службу
PeriodicTask myPeriodicTask = ScheduledActionService.Find(AGENT_NAME) as PeriodicTask;
//если нашли
if (myPeriodicTask != null)
{
try
{
//удаляем
ScheduledActionService.Remove(AGENT_NAME);
RemoveIsolatedStorage();
MessageBox.Show("Служба остановлена.");
}
catch (Exception ex)
{
MessageBox.Show("Невозможно удалить службу: " + ex.Message);
}
}
}
Задание
Изменить приложение "RSS-новости", добавив поддержку фоновой загрузки RSS-файлов. Добавить для приложения двусторонний тайл.
Освоение
Описание
Откроем ранее созданный проект "RSS-новости". Добавим два изображения размера 173x173 (для тайлов). Назовем их, например, "RSSred.png" и "RSSblue.png". Установим для данных изображений свойство "Build Action" в "Content".
Примечание: тайлы – это изображения, отображающиеся на главной странице Windows Phone 7. Они могут иметь пояснительные надписи и обратную сторону – другое изображение, которое будет периодически появляться. Для того чтобы добавить тайл приложения на главную страницу, в списке приложений нажмите на ваше приложение и удерживайте. В появившемся контекстном меню выберете "pin to start" Рис. 5.2 :
(рис 5.2) Отображение тайла приложения на главной странице
В код главной страницы добавим функцию установки тайла. Для основной картинки будем задавать RSSred.png, для обратной RSSblue.png.
private void SetTile()
{
ShellTile apptile = ShellTile.ActiveTiles.First();
StandardTileData appTileData = new StandardTileData();
appTileData.Title = "RSS новости";
appTileData.Count = 0;
appTileData.BackgroundImage = new Uri("/RSSred.png", UriKind.RelativeOrAbsolute);
appTileData.BackTitle = "RSS новости";
appTileData.BackContent = "Обратная сторона";
appTileData.BackBackgroundImage = new Uri("/RSSblue.png", UriKind.RelativeOrAbsolute);
apptile.Update(appTileData);
}
В конструктор класса добавим:
SetTile();
Также в коде должна быть добавлена директива:
using Microsoft.Phone.Shell;
Теперь добавим запуск запроса на фоновую загрузку RSS-файла. Для этого в конструктор класса добавим проверку, что в изолированном хранилище приложения присутствует специальная папка, в которую можно загружать файлы, используя фоновые сервисы: "/shared/transfers":
using (IsolatedStorageFile rssStore = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!rssStore.DirectoryExists("/shared/transfers"))
{
rssStore.CreateDirectory("/shared/transfers");
}
}
В код добавим директиву:
using Microsoft.Phone.BackgroundTransfer;
В функции LoadRSS() будем запускать фоновую загрузку нужного файла, а также подписываться на изменение статуса загрузки:
private void LoadRSS(Uri url)
{
BackgroundTransferRequest transferRequest = new BackgroundTransferRequest(url);
transferRequest.Method = "GET";
string strRSSFileName = "";
switch (m_nRssLoadIndex)
{
case 0:
strRSSFileName = strIStoragePolit;
break;
case 1:
strRSSFileName = strIStorageEconom;
break;
case 2:
strRSSFileName = strIStorageSport;
break;
case 3:
strRSSFileName = strIStorageMusic;
break;
case 4:
strRSSFileName = strIStorageMsdn;
break;
default:
MessageBox.Show("Ошибка при загрузке новостей.");
return;
}
Uri downloadUri = new Uri("shared/transfers/" + strRSSFileName, UriKind.RelativeOrAbsolute);
transferRequest.DownloadLocation = downloadUri;
transferRequest.TransferStatusChanged += new EventHandler<BackgroundTransferEventArgs>
(transferRequest_TransferStatusChanged);
try
{
BackgroundTransferService.Add(transferRequest);
}
catch (Exception ex)
{
MessageBox.Show("Невозможно запустить фоновую загрузку:" + ex.Message);
}
}
По завершении загрузки будем удалять фоновую загрузку, затем копировать загруженный файл из папки "/shared/transfers/" в корень изолированного хранилища, а затем работать с файлом, как прежде.
void transferRequest_TransferStatusChanged(object sender, BackgroundTransferEventArgs e)
{
//если скачивание прошло успешно - копируем файл и обновляем UI
if (e.Request.TransferStatus == TransferStatus.Completed)
{
try
{
BackgroundTransferService.Remove(e.Request);
}
catch (Exception ex)
{
MessageBox.Show("Невозможно удалить завершенную фоновую загрузку:" + ex.Message);
}
using (IsolatedStorageFile rssStore = IsolatedStorageFile.GetUserStoreForApplication())
{
string strRSSFileName = "";
switch (m_nRssLoadIndex)
{
case 0:
strRSSFileName = strIStoragePolit;
break;
case 1:
strRSSFileName = strIStorageEconom;
break;
case 2:
strRSSFileName = strIStorageSport;
break;
case 3:
strRSSFileName = strIStorageMusic;
break;
case 4:
strRSSFileName = strIStorageMsdn;
break;
default:
MessageBox.Show("Ошибка при загрузке новостей.");
return;
//break;
}
if (rssStore.FileExists("/shared/transfers/" + strRSSFileName))
{
rssStore.CopyFile("/shared/transfers/" + strRSSFileName, strRSSFileName, true);
string strRSSNews = LoadFromIsolatedStorage(strRSSFileName);
ParseAndDislayRSS(strRSSNews, false);
}
}
}
}
Теперь всю функциональность, касающуюся WebClient, можно убрать.
Задание
Создать приложение для Windows Phone 7, проигрывающее музыку в фоне. Предусмотреть возможность перехода к предыдущей/следующей песне и постановки на паузу. Добавить для приложения тайл, который будет меняться при проигрывании песни.
Освоение
Описание
Создадим новый проект Silverlight for Windows Phone – Windows Phone Application.
Добавим в него папку Audio, а в нее несколько аудио-файлов, формат которых поддерживает Windows Phone 7. Установим значение свойства "Build Action" в "Content", а "Copy to Output Directory" в "Copy if newer".
Добавим два изображения размера 173x173 (для тайлов). Назовем их, например, "Tile1.png" и "Tile2.png". Установим для данных изображений свойство "Build Action" в "Content".
Примечание: тайлы – это изображения, отображающиеся на главной странице Windows Phone 7. Они могут иметь пояснительные надписи и обратную сторону – другое изображение, которое будет периодически появляться. Для того чтобы добавить тайл приложения на главную страницу, в списке приложений нажмите на ваше приложение и удерживайте. В появившемся контекстном меню выберете "pin to start" Рис. 5.3 :
(рис 5.3) Отображение тайла приложения на главной странице
В код главной страницы добавим функцию установки тайла. При проигрывании мелодии в параметр IsPlay будем передавать true, в противном случае – false.
private void SetTile(bool IsPlay = false)
{
ShellTile apptile = ShellTile.ActiveTiles.First();
StandardTileData appTileData = new StandardTileData();
appTileData.Title = "";
appTileData.Count = 0;
if (IsPlay)
{
appTileData.BackgroundImage = new Uri("/Tile2.png", UriKind.RelativeOrAbsolute);
}
else
{
appTileData.BackgroundImage = new Uri("/Tile1.png", UriKind.RelativeOrAbsolute);
}
apptile.Update(appTileData);
}
В конструктор класса добавим:
SetTile();
Также в коде должна быть добавлена директива:
using Microsoft.Phone.Shell;
Теперь добавим в решение (solution) новый проект Silverlight for Windows Phone – Windows Phone Audio Playback Agent. В наш основной проект добавим ссылку на данный проект: Add Reference… – Projects - <имя проекта аудио-плейера>.
В файл AudioPlayer.cs добавим директиву:
using System.Collections.Generic;
Затем в класс добавим две глобальные переменные: номер текущей песни и список песен. В список песен сразу добавим имена файлов наших песен. Также можно указать название, автора и альбом.
private static int currentTrackNumber = 0;
private static List<AudioTrack>_playList = new List<AudioTrack>
{
new AudioTrack(new Uri("Elena Gheorghe - Balkan Girls.mp3", UriKind.Relative),
"Balkan Girls",
"Elena Gheorghe",
"Eurovision 2010",
null),
new AudioTrack(new Uri("Lara Fabian - I Guess I Loved You.mp3", UriKind.Relative),
"I Guess I Loved You",
"Lara Fabian",
"Unknown",
null),
new AudioTrack(new Uri("velvet-prodavec_kukol.mp3", UriKind.Relative),
"Продавец кукол",
"Вельвет",
"Unknown",
null),
//remote URI
new AudioTrack(new Uri("http://traffic.libsyn.com/wpradio/WPRadio_29.mp3", UriKind.Absolute),
"Episode 29",
"Windows Phone Radio",
"Windows Phone Radio Podcast",
null)
};
Добавим в класс три метода:
private void PlayNextTrack(BackgroundAudioPlayer player)
{
if (++currentTrackNumber >= _playList.Count)
{
currentTrackNumber = 0;
}
PlayTrack(player);
}
private void PlayPreviousTrack(BackgroundAudioPlayer player)
{
if (--currentTrackNumber < 0)
{
currentTrackNumber = _playList.Count - 1;
}
PlayTrack(player);
}
private void PlayTrack(BackgroundAudioPlayer player)
{
// Sets the track to play. When the TrackReady state is received,
// playback begins from the OnPlayStateChanged handler.
player.Track = _playList[currentTrackNumber];
}
Изменим функции OnPlayStateChanged() и OnUserAction() :
protected override void OnPlayStateChanged(BackgroundAudioPlayer player,
AudioTrack track, PlayState playState)
{
switch (playState)
{
case PlayState.TrackReady:
// The track to play is set in the PlayTrack method.
player.Play();
break;
case PlayState.TrackEnded:
PlayNextTrack(player);
break;
}
NotifyComplete();
}
protected override void OnUserAction(BackgroundAudioPlayer player,
AudioTrack track, UserAction action, object param)
{
switch (action)
{
case UserAction.Play:
if (isPaused)
player.Play();
else
PlayTrack(player);
isPaused = false;
break;
case UserAction.Pause:
player.Pause();
isPaused = true;
break;
case UserAction.SkipPrevious:
PlayPreviousTrack(player);
isPaused = false;
break;
case UserAction.SkipNext:
PlayNextTrack(player);
isPaused = false;
break;
}
NotifyComplete();
}
Теперь откроем файл App.xaml основного проекта.
Добавим 2 директивы:
using System.IO.IsolatedStorage; using System.Windows.Resources;
Поскольку фоновый аудио-проигрыватель умеет воспроизводить музыку только из изолированного проигрывателя, добавим в класс App функцию, которая будет копировать в проигрыватель песни из ресурсов. Вызов функции добавим в конструктор класса.
private void CopyToIsolatedStorage()
{
using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
{
string[] files = new string[] { "Elena Gheorghe - Balkan Girls.mp3",
"Lara Fabian - I Guess I Loved You.mp3",
"velvet-prodavec_kukol.mp3" };
foreach (var _fileName in files)
{
if (!storage.FileExists(_fileName))
{
string _filePath = "Audio/" + _fileName;
StreamResourceInfo resource = Application.GetResourceStream(new Uri(_filePath, UriKind.Relative));
using (IsolatedStorageFileStream file = storage.CreateFile(_fileName))
{
int chunkSize = 4096;
byte[] bytes = new byte[chunkSize];
int byteCount;
while ((byteCount = resource.Stream.Read(bytes, 0, chunkSize)) > 0)
{
file.Write(bytes, 0, byteCount);
}
}
}
}
}
}
Вернемся к главной странице. В файл разметки добавим несколько текстовых блоков для вывода информации о текущей песне и меню, состоящее из 3 кнопок: назад, воспроизведение/пауза, вперед.
Теперь перейдем к коду главной страницы. Добавим директиву:
using Microsoft.Phone.BackgroundAudio;
В конструкторе подпишемся на изменение состояния воспроизведения:
BackgroundAudioPlayer.Instance.PlayStateChanged += new EventHandler(Instance_PlayStateChanged);
Добавим обработчик события:
void Instance_PlayStateChanged(object sender, EventArgs e)
{
switch (BackgroundAudioPlayer.Instance.PlayerState)
{
case PlayState.Playing:
((ApplicationBarIconButton)ApplicationBar.Buttons[1])
.IconUri = new Uri(PATH_TO_PAUSE_IMG, UriKind.Relative);
SetTile(true);
break;
case PlayState.Paused:
case PlayState.Stopped:
((ApplicationBarIconButton)ApplicationBar.Buttons[1])
.IconUri = new Uri(PATH_TO_PLAY_IMG, UriKind.Relative);
SetTile(false);
break;
}
if (null != BackgroundAudioPlayer.Instance.Track)
{
txtAuthor.Text = BackgroundAudioPlayer.Instance.Track.Artist;
txtAlbum.Text = BackgroundAudioPlayer.Instance.Track.Album;
txtDur.Text = String.Format("{0:00}", BackgroundAudioPlayer.Instance.Track.Duration.Minutes) + ":" +
String.Format("{0:00}", BackgroundAudioPlayer.Instance.Track.Duration.Seconds);
PageTitle.Text = BackgroundAudioPlayer.Instance.Track.Title;
...
}
}
Обработчики нажатий на кнопки меню:
private void Menu1_Click(object sender, EventArgs e)
{
BackgroundAudioPlayer.Instance.SkipPrevious();
}
private void Menu2_Click(object sender, EventArgs e)
{
if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
{
BackgroundAudioPlayer.Instance.Pause();
}
else
{
BackgroundAudioPlayer.Instance.Play();
}
}
private void Menu3_Click(object sender, EventArgs e)
{
BackgroundAudioPlayer.Instance.SkipNext();
}
При закрытии приложения музыка будет продолжать воспроизводиться. При повторном открытии приложения будем выдавать пользователю информацию о текущей песне. Для этого переопределим метод OnNavigatedTo() главной страницы:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
//если при хагрузке приложения уже играет музыка
if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
{
txtAuthor.Text = BackgroundAudioPlayer.Instance.Track.Artist;
txtAlbum.Text = BackgroundAudioPlayer.Instance.Track.Album;
txtDur.Text = String.Format("{0:00}", BackgroundAudioPlayer.Instance.Track.Duration.Minutes) + ":" +
String.Format("{0:00}", BackgroundAudioPlayer.Instance.Track.Duration.Seconds);
PageTitle.Text = BackgroundAudioPlayer.Instance.Track.Title;
((ApplicationBarIconButton)ApplicationBar.Buttons[1])
.IconUri = new Uri(PATH_TO_PAUSE_IMG, UriKind.Relative);
...
}
else
{
txtAuthor.Text = "";
txtAlbum.Text = "";
txtDur.Text = "";
PageTitle.Text = PAGE_DEFAULT_TITLE_TEXT;
((ApplicationBarIconButton)ApplicationBar.Buttons[1]).IconUri =
new Uri(PATH_TO_PLAY_IMG, UriKind.Relative);
...
}
}
Задание
Изменить приложение "Список задач", добавив установку напоминаний. Добавить для приложения двусторонний тайл.
Освоение
Описание
Откроем проект "Список задач". Добавим два изображения размера 173x173 (для тайлов). Назовем их, например, "Front.png" и "Background.png". Установим для данных изображений свойство "Build Action" в "Content".
Примечание: тайлы – это изображения, отображающиеся на главной странице Windows Phone 7. Они могут иметь пояснительные надписи и обратную сторону – другое изображение, которое будет периодически появляться. Для того чтобы добавить тайл приложения на главную страницу, в списке приложений нажмите на ваше приложение и удерживайте. В появившемся контекстном меню выберете "pin to start" Рис. 5.4 :
(рис 5.4) Отображение тайла приложения на главной странице
В код главной страницы добавим функцию установки тайла. В качестве основной картинки установим "Front.png", в качестве обратной – "Background.png".
private void SetTile()
{
ShellTile apptile = ShellTile.ActiveTiles.First();
StandardTileData appTileData = new StandardTileData();
appTileData.Title = "Список задач";
appTileData.Count = 0;
appTileData.BackgroundImage = new Uri("/Front.png", UriKind.RelativeOrAbsolute);
appTileData.BackTitle = "Список задач";
appTileData.BackContent = "Обратная сторона";
appTileData.BackBackgroundImage = new Uri("/Background.png", UriKind.RelativeOrAbsolute);
apptile.Update(appTileData);
}
В конструктор класса добавим:
SetTile();
Также в коде должна быть добавлена директива:
using Microsoft.Phone.Shell;
В код страницы AddItem.xaml добавим директиву, необходимую для установки напоминаний:
using Microsoft.Phone.Scheduler;
В класс добавим две константы: базовое имя напоминания (напоминание должно иметь уникальное имя, которое мы будем создавать на основе базового, например, добавлением номера) и максимальное количество.
private const string REMINDER_BASE_NAME = "reminder";
private const int MAX_REMINDER_COUNT = 3;
Функцию генерации имени рекомендуется написать самостоятельно.
Изменим функцию добавления напоминания:
private void btnSet_Click(object sender, RoutedEventArgs e)
{
//генерируем имя напоминания
string strName = GenerateReminderName();
if (!strName.Equals(""))
{
if (!txtTitle.Text.Trim().Equals("") !txtText.Text.Trim().Equals(""))
{
DateTime date = (DateTime)ToDoItemDate.Value;
DateTime time = (DateTime)ToDoItemTime.Value;
DateTime beginTime = date + time.TimeOfDay;
if (beginTime > DateTime.Now)
{
CreateReminder(strName, beginTime);
NavigationService.GoBack();
}
else
{
MessageBox.Show("Невозможно установить задачу на прошлое.");
}
}
else
{
MessageBox.Show("Не все поля заполнены.");
}
}
else
{
MessageBox.Show("Нельзя создать больше " + MAX_REMINDER_COUNT + " задач.");
}
}
private void CreateReminder(string strName, DateTime beginTime)
{
Reminder myReminder = new Reminder(strName);
myReminder.Title = txtTitle.Text;
myReminder.Content = txtText.Text;
myReminder.RecurrenceType = RecurrenceInterval.None;
myReminder.BeginTime = beginTime;
myReminder.ExpirationTime = beginTime.AddMinutes(5);
myReminder.NavigationUri = new Uri("/MainPage.xaml", UriKind.Relative);
ScheduledActionService.Add(myReminder);
}
Свойство NavigationUri задает ссылку на страницу приложения, которая должна быть запущена при нажатии на напоминание.
Вернемся к коду главной страницы. Добавим функцию инициализации списка. Будем получать коллекцию напоминаний, считать их количество и обновлять тайл (свойству count задавать количество зарегистрированных напоминаний):
private void InitList()
{
listToDo.ItemsSource = ScheduledActionService.GetActions<ScheduledNotification>();
int count = 0;
foreach (Reminder ri in listToDo.ItemsSource)
{
count++;
}
//update tile
ShellTile apptile = ShellTile.ActiveTiles.First();
StandardTileData appTileData = new StandardTileData();
appTileData.Count = count;
apptile.Update(appTileData);
}
Не забудем добавить пространство имен для кода главной страницы Microsoft.Phone.Scheduler.
В связи с новой функциональностью перепишем метод OnNavigatedTo() и обработчик нажатия на кнопку "Удалить":
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
InitList();
}
private void MenuRemove_Click(object sender, EventArgs e)
{
if (-1 != listToDo.SelectedIndex)
{
string strName = ((Reminder)listToDo.SelectedItem).Name;
if (null != ScheduledActionService.Find(strName))
{
ScheduledActionService.Remove(strName);
InitList();
}
}
else
{
MessageBox.Show("Нет выделенных элементов.");
}
}
Также перепишем разметку страницы с использованием шаблонов (источник данных для списка задается в функции InitList()):
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox Name="listToDo">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Title}" FontSize="26" FontWeight="Bold" />
<TextBlock Text="{Binding Content}" FontSize="24" TextWrapping="Wrap" />
<TextBlock Text="{Binding BeginTime}" FontSize="24" FontStyle="Italic" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Задание
Создать приложение для Windows Phone 7, позволяющее устанавливать ежедневные будильники с возможностью выбора мелодии. Приложение должно иметь свой тайл.
Освоение
Описание
Создадим новый проект Silverlight for Windows Phone – Windows Phone Application.
Добавим изображение размера 173x173 (для тайла). Назовем его, например, "Front.png". Установим для данных изображений свойство "Build Action" в "Content".
Примечание: тайлы – это изображения, отображающиеся на главной странице Windows Phone 7. Они могут иметь пояснительные надписи и обратную сторону – другое изображение, которое будет периодически появляться. Для того чтобы добавить тайл приложения на главную страницу, в списке приложений нажмите на ваше приложение и удерживайте. В появившемся контекстном меню выберете "pin to start" Рис. 5.5:
(рис 5.5) Отображение тайла приложения на главной странице
В код главной страницы добавим функцию установки тайла:
private void SetTile()
{
ShellTile apptile = ShellTile.ActiveTiles.First();
StandardTileData appTileData = new StandardTileData();
appTileData.Title = "Будильник";
appTileData.Count = 0;
appTileData.BackgroundImage = new Uri("/Front.png", UriKind.RelativeOrAbsolute);
apptile.Update(appTileData);
}
В конструктор класса добавим:
SetTile();
Также в коде должна быть добавлена директива:
using Microsoft.Phone.Shell;
Создадим в проекте папку Audio. Добавим в нее несколько музыкальных файлов формата, который поддерживается Windows Phone 7. Свойство "Build Action" для этих файлов установим в "Content".
Добавим в проект страницу AddAlarm.xaml. В References добавим пространство имен Microsoft.Phone.Controls.Toolkit. Основное содержимое разметки будет выглядеть следующим образом:
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel Margin="15,15,0,0">
<TextBlock Text="Текст:" FontSize="26" />
<TextBox Name="txtText" FontSize="26" />
<TextBlock Text="Мелодия:" FontSize="26" VerticalAlignment="Center" />
<toolkit:ListPicker Name="lpSound">
<toolkit:ListPickerItem Content="After Forever - Living Shields.mp3" />
<toolkit:ListPickerItem Content="Ancient Bards - The Birth Of Evil.mp3" />
</toolkit:ListPicker>
<TextBlock Text="Время:" FontSize="26" VerticalAlignment="Center" />
<toolkit:TimePicker Name="ToDoItemTime"/>
<StackPanel Orientation="Horizontal" Margin="0,20,0,0">
<Button Name="btnBack" Content="<-" Width="100" Click="btnBack_Click" />
<Button Name="btnSet" Content="Установить" Width="340" Click="btnSet_Click" />
</StackPanel>
</StackPanel>
</Grid>
Элемент управления ListPicker будет содержать названия файлов с мелодиями.
В коде страницы добавим директиву, необходимую для установки напоминаний:
using Microsoft.Phone.Scheduler;
В класс добавим две константы: базовое имя будильника (будильник должен иметь уникальное имя, которое мы будем создавать на основе базового, например, добавлением номера) и максимальное количество будильников.
private const string ALARM_BASE_NAME = "alarm";
private const int MAX_ALARM_COUNT = 3;
Функцию генерации имени рекомендуется написать самостоятельно.
Добавим функции создания будильников:
private void btnSet_Click(object sender, RoutedEventArgs e)
{
//генерируем имя напоминания
string strName = GenerateAlarmName();
if (!strName.Equals(""))
{
if (!txtText.Text.Trim().Equals(""))
{
DateTime beginTime = (DateTime)ToDoItemTime.Value;
CreateAlarm(strName, beginTime);
}
else
{
MessageBox.Show("Не все поля заполнены.");
}
}
else
{
MessageBox.Show("Нельзя создать больше " + MAX_ALARM_COUNT + " будильников.");
}
}
private void CreateAlarm(string strName, DateTime beginTime)
{
Alarm myAlarm = new Alarm(strName);
myAlarm.Content = txtText.Text;
string strAudio = "/Audio/" + ((ListPickerItem)lpSound.SelectedItem).Content;
myAlarm.Sound = new Uri(strAudio, UriKind.Relative);
myAlarm.RecurrenceType = RecurrenceInterval.Daily;
myAlarm.BeginTime = beginTime;
ScheduledActionService.Add(myAlarm);
}
Перейдем к коду главной страницы. Добавим функцию инициализации списка. Будем получать коллекцию будильников, считать их количество и обновлять тайл (свойству count задавать количество зарегистрированных будильников):
private void InitList()
{
listAlarms.ItemsSource = ScheduledActionService.GetActions<ScheduledNotification>();
int count = 0;
foreach (Alarm ri in listAlarms.ItemsSource)
{
count++;
}
//update tile
ShellTile apptile = ShellTile.ActiveTiles.First();
StandardTileData appTileData = new StandardTileData();
appTileData.Count = count;
apptile.Update(appTileData);
}
Не забудем добавить пространство имен для кода главной страницы Microsoft.Phone.Scheduler.
Вызывать функцию инициализации будем в методе OnNavigatedTo():
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
InitList();
}
Напишем разметку страницы с использованием шаблонов (источник данных для списка задается в функции InitList()):
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox Name="listAlarms">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Title}" FontSize="26"
TextWrapping="NoWrap" FontWeight="Bold" />
<TextBlock Text="{Binding Content}" FontSize="24"
TextWrapping="Wrap" />
<TextBlock Text="{Binding BeginTime}" FontSize="24"
FontStyle="Italic" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Добавим две кнопки в меню: добавление нового будильника и удаление.
<!--Sample code showing usage of ApplicationBar-->
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBarIconButton IconUri="/Images/appbar.add.rest.png"
Text="добавить" Click="MenuAdd_Click" />
<shell:ApplicationBarIconButton IconUri="/Images/appbar.delete.rest.png"
Text="удалить" Click="MenuRemove_Click" />
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
Напишем обработчик нажатия на кнопку удаления:
private void MenuRemove_Click(object sender, EventArgs e)
{
if (-1 != listAlarms.SelectedIndex)
{
string strName = ((Alarm)listAlarms.SelectedItem).Name;
if (null != ScheduledActionService.Find(strName))
{
ScheduledActionService.Remove(strName);
InitList();
}
}
else
{
MessageBox.Show("Нет выделенных элементов.");
}
}
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.