Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторный_практикум.doc
Скачиваний:
74
Добавлен:
15.11.2019
Размер:
45.35 Mб
Скачать

4. Модификация приложения Silverlight: простой проигрыватель mp3-файлов

Простой проигрыватель MP3-файлов. Для начала добавим два простеньких класса. Один класс будет отвечать за свойства MP3-файла: имя и путь. Добавим класс для проекта WPF-приложения: выделим имя проекта (LWP17Silverlight) и выполним: Проект -> Добавить класс... (Shift+Alt+C): в открывшемся окне в поле Имя указываем DataItem.cs. Код файла будет таким:

using System;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Ink;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

namespace LWP17Silverlight

{

public class DataItem

{

private string nameItem;

private string pathItem;

public string NameItem

{

get { return nameItem; }

set { nameItem = value; }

}

public string PathItem

{

get { return pathItem; }

set { pathItem = value; }

}

}

}

Второй класс будет содержать всего две функции, которые будут работать со временем воспроизведения файла. Класс назовём ProgressConverter (файл ProgressConverter.cs) с кодом:

using System;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Ink;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using System.Windows.Data;

namespace LWP17Silverlight

{

public class ProgressConverter : IValueConverter

{

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

{

return ((TimeSpan)value).TotalSeconds;

}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

{

return TimeSpan.FromSeconds((double)value);

}

}

}

В файле MainPage.xaml в коде XAML найдём:

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

Добавим после:

xmlns:lwp17="clr-namespace:LWP17Silverlight"

Найдём:

mc:Ignorable="d" d:DesignHeight="480" d:DesignWidth="640" KeyDown="UserControl_KeyDown">

Добавим после:

<UserControl.Resources>

<lwp17:ProgressConverter x:Key="progress"></lwp17:ProgressConverter>

</UserControl.Resources>

Основным элементом, реализующим работу непосредственно «начинки» проигрывателя станет MediaElement (Панель элементов: ). Добавляем его на страницу в ячейку [0, 1] (строка: 0, столбец: 1). Код элемента будет таким:

<MediaElement x:Name="mediaElement" Grid.Column="1" Height="23" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Width="Auto" AutoPlay="True" IsMuted="False" Stretch=”Fill” />

Установленные свойства:

XAML-код имени элемента:

x:Name=”mediaElement”

AutoPlay:

True

Stretch:

Fill

HorizontalAligment:

Stretch

VetricalAligment:

Bottom

Height:

23

Width:

Auto

IsMuted:

Нет галочки

Второй немаловажный элемент нашего проигрывателя, будет являться списком всех доступных композиций для прослушивания. Список мы поместим в DataGrid и будем выводить в нём композиции по имени, записанному в специальном XML-файле нашего «сайта».

Перетягиваем с панели элементов в самую правую внизу страницы [4, 1] DataGrid ( ). Код, основанный на изменении свойств элемента:

<sdk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding}" Grid.Column="1" Grid.Row="4" Height="Auto" HorizontalAlignment="Stretch" Name="songList" VerticalAlignment="Stretch" Width="Auto" DataContext="{Binding}" />

Не забудем привязать данные к свойствам DataContext и ItemSource:

Для этого выберем любое из свойств, нажмём на Привязка..., далее в пункте Источник дважды щёлкнем по DataContext.

Далее редактируем свойство Columns (жмём «...»):

Рис. 4. 1. Редактор коллекции: Columns

В списке Выбрать элемент выбираем DataGridTextColumn, жмём дважды добавить. Свойства первого столбца такие:

XAML-код поля привязки:

Binding=”{Binding NameItem}”

ACanUserSort:

Нет галочки

Header:

Имя композиции

IsReadOnly:

Галочка

Width:

Auto

Для второго столбца:

XAML-код поля привязки:

Binding=”{Binding PathItem}”

ACanUserSort:

Нет галочки

Header:

Путь к композиции

IsReadOnly:

Галочка

Width:

Star

Итоговый XAML-код:

<sdk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding}" Grid.Column="1" Grid.Row="4" Height="Auto" HorizontalAlignment="Stretch" Name="songList" VerticalAlignment="Stretch" Width="Auto" DataContext="{Binding}">

<sdk:DataGrid.Columns>

<sdk:DataGridTextColumn Binding="{Binding NameItem}" CanUserReorder="True" CanUserResize="True" CanUserSort="False" Header="Имя композиции" IsReadOnly="True" Width="Auto" />

<sdk:DataGridTextColumn Binding="{Binding PathItem}" CanUserReorder="True" CanUserResize="True" CanUserSort="False" Header="Путь к композиции" IsReadOnly="True" Width="*" />

</sdk:DataGrid.Columns>

</sdk:DataGrid>

Дальше последовательно размещаем остальные элементы проигрывателя. Выглядеть это будет следующим образом:

Рис. 4. 2. Расстановка элементов на странице MainPage.xaml проекта WPF приложения Silverlight

Первым элемент будет являться шапкой нашего MP3-проигрывателя с простым текстовым блоком. Расположим его в [0, 1] ячейке сетки. Код TextBlock будет таким:

<TextBlock FontSize="20" Height="34" Name="tbTitle" Text="Простой проигрыватель MP3-файлов" VerticalAlignment="Center" Width="Auto" Grid.Column="1" HorizontalAlignment="Center" />

Чуть ниже в ячейке [1, 1] расположим элемент, выполняющий функции временной дорожки композиции (расположение ползунка будет отвечать за положение на шкале воспроизведения файла), а также два TextBlock. Первый будет статическими, второй же будет отражать текущий статус воспроизведений:

<TextBlock Grid.Row="1" Grid.Column="1" Height="23" HorizontalAlignment="Center" Name="textBlock4" Text="Воспроизведение:" VerticalAlignment="Top" Width="106" />

<TextBlock Grid.Row="1" Grid.Column="1" Height="23" HorizontalAlignment="Center" Name="textBlock5" Text="Статус:" VerticalAlignment="Bottom" Width="Auto" />

Временная дорожка: Slider ( ). Привязку (свойство Value для элемента Slider) данных к ползунку (Position) осуществим через класс ProgressConvetrter на основе данных элемента medaiElement:

XAML-код элемента будет таким:

<Slider x:Name="sliderProcess" Grid.Row="1" Grid.Column="1" Minimum="0" Maximum="230" Value="{Binding ElementName=mediaElement, Path=Position, Mode=TwoWay, Converter={StaticResource progress}}" IsEnabled="False" />

В ячейку [2, 1] вставим кнопки проигрывателя и два дополнительных слайдера. Кнопки, последовательно будут выполнять функции: остановки, воспроизведения, паузы и выключения звука. Первый слайдер будет ответственен за уровень громкости, второй за баланс левого и правого наушника (колонки) в режиме стерео-воспроизведения.

Кнопка «Стоп»:

<Button x:Name="buttonStop" Content="Стоп" Grid.Row="2" Grid.Column="1" Width="70" Height="23" HorizontalAlignment="Left" VerticalAlignment="Center"></Button>

Кнопка «Воспроизвести:

<Button x:Name="buttonPlay" Content="Воспроизвести" Grid.Row="2" Grid.Column="1" Width="100" Height="23" HorizontalAlignment="Left" Margin="70,23,0,23" VerticalAlignment="Center"></Button>

Кнопка «Пауза»:

<Button x:Name="buttonPause" Content="Пауза" Grid.Row="2" Grid.Column="1" Width="70" Height="23" HorizontalAlignment="Left" Margin="170,23,0,23" VerticalAlignment="Center"></Button>

Кнопка «Заглушить»:

<Button x:Name="buttonMuted" Content="Заглушить" Grid.Row="2" Grid.Column="1" Width="70" Height="23" HorizontalAlignment="Left" Margin="240,23,0,23" VerticalAlignment="Center"></Button>

TextBlock и Slider отвечающий за громкость:

<Slider LargeChange="0.1" Maximum="1" SmallChange="0.01" Value="{Binding Volume, ElementName=mediaElement, Mode=TwoWay, UpdateSourceTrigger=Default}" Grid.Column="1" Grid.Row="2" Height="25" VerticalAlignment="Top" HorizontalAlignment="Right" Width="94" />

<TextBlock Height="23" HorizontalAlignment="Right" Margin="0,0,98,0" Name="textBox6" Text="Громкость:" VerticalAlignment="Top" Grid.Column="1" Grid.Row="2" />

TextBlock и Slider отвечающий за баланс:

<Slider LargeChange="0.1" Maximum="1" Minimum="-1" Name="sliderBalance" Value="{Binding Path=Balance, ElementName=mediaElement, Mode=TwoWay, UpdateSourceTrigger=Default}" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Right" Width="94" Height="25" VerticalAlignment="Bottom" />

<TextBlock Height="23" HorizontalAlignment="Right" Margin="0,0,116,0" Name="textBox7" Text="Баланс:" VerticalAlignment="Bottom" Grid.Column="1" Grid.Row="2" />

В ячейку [3, 1] вставляем единственный TextBlock:

<TextBlock FontSize="12" Height="23" HorizontalAlignment="Center" Name="textBlock8" Text="Список доступных MP3-файлов:" VerticalAlignment="Center" Width="Auto" Grid.Column="1" Grid.Row="3" />

Перед тем, как работать с событиями элементов и кодом приложения, добавим необходимые ресурсы «сайта» (веб-проекта). Создаём последовательно две папки (Resource -> MP3). Для создания папки выделяем имя веб-проекта, далее выполняем Проект -> Создать папку:

Собственно веб-проект и импорт ресурсов MP3-файлов в конечную папку проекта необходим для «эмуляции» работы приложения Silverlight с неким сайтом. В конечном итоге, страница с Silverlight-приложением получает удалённо сами файлы (путь, имя файла и содержимое).

В конечную папку импортируем несколько композиций, выполняем: Проект -> Добавить существующий элемент... (Shift+Alt+A). Пусть в этой папке будут храниться несколько MP3-файлов:

Теперь в папке Resource создаём XML-файл с именем MusicList.xml (Проект -> Добавить новый элемент... (Ctrl+Shift+A), следующего содержания:

<?xml version="1.0" encoding="utf-8" ?>

<root>

<music open="1" path="Resource/MЗ3/Atrium_Sun_-_Abyss_(Original_Mix).mp3" name="Abyss (Original Mix)">Atrium Sun</music>

<music open="1" path="Resource/MP3/Daniel_Barbosa_-_Asian_Gardens_(Feat._Shen_Shen).mp3" name="Asian Gardens (Feat. Shen Shen)">Daniel Barbosa</music>

<music open="1" path="Resource/MP3/Elena_-_Zombie_(Ambient_Vocal_Edit).mp3" name="Zombie (Ambient Vocal Edit)">Elena</music>

</root>

Атрибуты для элемента music:

path: содержит полный путь до файла с указанием имени файла и расширения;

name: содержит отображаемое в списке имя (для страницы);

значение: содержит автора композиции.

Перейдём к функциональности кода главной страницы MainPage.xaml.cs: в начало файла добавим следующий код:

// Для MP3-проигрывателя

using System.Xml;

using System.IO;

using System.Windows.Threading;

using System.Windows.Browser;

Найдём:

public MainPage()

{

Добавим до:

public List<DataItem> DataItems;

public bool boolIsMuted = false;

private TimeSpan timeDuration; // Интервал времени

Найдём:

// Подключаем событие Loaded чтобы подключить события на этапе загрузки страницы

this.Loaded += new RoutedEventHandler(MainPage_Loaded);

Добавим после:

this.XmlProcessMethod();

Найдём:

// Переключение в полноэкранный или оконный режимы

App.Current.Host.Content.IsFullScreen = !App.Current.Host.Content.IsFullScreen;

}

Добавим после:

/// <summary>

/// Функция использует асинхронную загрузку данных из XML-файла

/// и подписывается на событие для объекта WebClient DownLoadXmlComplete

/// и событие MeidaEnded объекта MediaElement

/// </summary>

private void XmlProcessMethod()

{

WebClient webClient = new WebClient();

webClient.DownloadStringAsync(new Uri(HtmlPage.Document.DocumentUri, "Resource/MusicList.xml"));

webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(this.DownLoadXmlComplete);

mediaElement.MediaEnded += new RoutedEventHandler(mediaElement_MediaEnded);

}

/// <summary>

/// Загрузка музыки согласно данные XML-файла и конвертирование данных в список.

/// Привязка свойства ItemSource элемента DataGrid к данному списку.

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void DownLoadXmlComplete(object sender, DownloadStringCompletedEventArgs e)

{

using (XmlReader reader = XmlReader.Create(new StringReader(e.Result)))

{

DataItems = new List<DataItem>();

while (reader.Read())

{

if (reader.IsStartElement() && reader.GetAttribute("open") == "1")

{

string pathMusic = reader.GetAttribute("path").ToString();

string nameMusic = reader.GetAttribute("name").ToString();

DataItem dataItem = new DataItem();

dataItem.NameItem = nameMusic;

dataItem.PathItem = pathMusic;

DataItems.Add(dataItem);

}

}

this.DataContext = DataItems;

}

}

Инициализируем события. Событие SelectionChanged элемента DataGrid:

private void songList_SelectionChanged(object sender, SelectionChangedEventArgs e)

{

sliderProcess.IsEnabled = true;

mediaElement.Position = new TimeSpan(0); // Обнуляем слайдер воспроизведения

DataItem selectItem = (DataItem)songList.SelectedItem; // Получаем выбранный в списке элемент

mediaElement.Source = new Uri(HtmlPage.Document.DocumentUri, selectItem.PathItem); // Меняем источник

mediaElement.Play(); // Запускаем композицию

textBlock4.Text = "Воспроизведение: " + selectItem.NameItem.ToString();

}

Событие MediaEnded элемента MediaElement:

private void mediaElement_MediaEnded(object sender, RoutedEventArgs e)

{

textBlock5.Text = "Статус: Воспроизведение завершено";

mediaElement.Pause();

mediaElement.Position = TimeSpan.Zero;

}

Событие MediaOpened элемента MediaElement:

private void mediaElement_MediaOpened(object sender, RoutedEventArgs e)

{

textBlock5.Text = "Статус: Воспроизведение начато";

// Получаем общее время композиции

timeDuration = mediaElement.NaturalDuration.HasTimeSpan ? mediaElement.NaturalDuration.TimeSpan : TimeSpan.FromMilliseconds(0);

sliderProcess.Maximum = timeDuration.TotalSeconds;

}

Событие CurrenyStateChanged элемента MediaElement:

private void mediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)

{

textBlock5.Text = "Статус: " + mediaElement.CurrentState.ToString();

if (mediaElement.CurrentState != MediaElementState.Playing

&& mediaElement.CurrentState != MediaElementState.Paused)

{ this.sliderProcess.IsEnabled = false; }

else { this.sliderProcess.IsEnabled = true; }

}

События Click элемента всех кнопок поочерёдно:

private void buttonStop_Click(object sender, RoutedEventArgs e)

{

mediaElement.Position = TimeSpan.Zero;

mediaElement.Stop();

}

private void buttonPlay_Click(object sender, RoutedEventArgs e)

{

mediaElement.Play();

}

private void buttonPause_Click(object sender, RoutedEventArgs e)

{

mediaElement.Pause();

}

private void buttonMuted_Click(object sender, RoutedEventArgs e)

{

if (!boolIsMuted)

{

textBlock5.Text = "Статус: Звук выключен";

buttonMuted.Content = "Включить";

mediaElement.IsMuted = true;

boolIsMuted = true;

}

else

{

textBlock5.Text = "Статус: Звук включен";

buttonMuted.Content = "Заглушить";

mediaElement.IsMuted = false;

boolIsMuted = false;

}

}

Компилируем, проверяем работоспособность. Запускаем страницу, выбираем любой MP3-файл в списке доступных файлов, слушаем (если конечно есть на чём слушать ), перемещаем ползунок по композиции, жмём на кнопку «Пауза», уменьшаем громкость, меняем баланс на левый наушник или на правый, выключаем и включаем звук.

Рис. 4. 3. Результат работы приложения Silverlight: воспроизведение выбранной композиции