Цель практического занятия: Целью данного занятия является знакомство с технологией
Файлы к практическому занятию Вы можете скачать здесь.
Подробно об алгоритмах работы
Один из самых известных примеров использования этой технологии – http://memorabilia.hardrock.com/ (рис. 18.1).
(рис 18.1) Применение технологии Deep Zoom на сайте Hard RockНаша задача – создать аналогичное приложение, в котором пользователь сможет просмотреть имеющиеся в Интернет-магазине велосипеды и узнать какую-либо информацию о выбранном товаре. Для того чтобы сделать подобное приложение, нам понадобится бесплатная программа Microsoft
После запуска программы
(рис 18.2) Импорт изображений в Deep Zoom ComposerНа втором этапе, необходимо из имеющихся изображений скомпоновать коллаж, при этом картинки можно уменьшать и увеличивать в размерах (сохраняя их разрешение), накладывать друг на друга (рис. 18.3).
(рис 18.3) Импорт изображений в Deep Zoom ComposerПомимо этого, на данном шаге можно сделать еще ряд действий, а именно: создать встроенное меню, которое позволит перемещаться от одного изображения к другому; установить ссылки между изображениями друг на друга так, чтобы при щелчке мышкой по одному изображению переходить к связанному; устанавливать внешние ссылки; задавать каждому изображение какое-либо строковое значение, которое потом можно будет использовать.
Меню создается во вкладке "Menu" путем перетаскивания изображений на панель редактирования. При помощи кнопок в верхней части панели можно задавать иерархию пунктов меню (рис. 18.4).
(рис 18.4) Создание меню в Deep Zoom Composer
Для того чтобы задать внутреннюю ссылку, необходимо выделить нужное изображение, вызвать контекстное меню Add Internal Link. Откроется окно со всеми изображениями, с которыми мы можем связать текущее изображение (рис. 18.5).
(рис 18.5) Окно добавления внутренний ссылки в Deep Zoom Composer
Для каждого изображения можно указать тег – строковое значение. Это позволит в дальнейшем идентифицировать выбранное пользователем изображение. Чтобы указать тег, необходимо выбрать изображение и в панель свойство указать нужное значение (рис. 18.6). Для каждого изображения укажем имя файла, в котором оно хранится.
(рис 18.6) Указание тега для изображения в Deep Zoom Composer
После того, как все приготовления сделаны, необходимо экспортировать получившийся коллаж. Это делается на последнем этапе.
(рис 18.7) Экспорт проекта в Deep Zoom ComposerВ результате экспорта будет создана папка, которая будет содержать файл Default.xap, файлы тестовых страниц и папку GeneratedImages. Каталог GeneratedImages в свою очередь состоит из двух каталогов, содержащих части изображений в различных масштабах и нескольких xml файлов. Файл dzc_output.xml описывает созданное Metadata.xml определяет коллекцию изображений и связанные с ними теги.
После того, как приложение разработано, необходимо встроить его в наш Интернет-магазин.
Для того чтобы интегрировать наше приложение в сайт, создадим еще одну страницу на основе мастера страниц master.master – products/ProductBrowser.aspx. Проще всего добавить на эту страницу компонент products/ProductBrowser.aspx в dzc_output.xml.
(рис 18.8) Добавление Deep Zoom на страницу в Microsoft Expression WebВ результате на самой странице будет сгенерирован следующий код:
<asp:Content ID="Content2" ContentPlaceHolderID="column_l_placeholder" runat="Server">
<div id="deepzoomcontainer">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2"
style="width: 640px; height: 480px;">
<param name="source" value="../deepzooms/dzc_output/deepzoomproject.xap" />
<param name="onerror" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="2.0.31005.0" />
<param name="autoUpgrade" value="true" />
<param name="initparams" value="zoomIn=5" />
<a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight"
style="border-style: none;" />
</a>
</object>
<iframe id="I1" style='visibility: hidden; height: 0; width: 0; border: 0px;' name="I1">
</iframe>
</div>
</asp:Content>
При этом в самом проекте будет создан каталог deepzooms, в который будет помещен файл deepzoomproject.xap и скопирована папка GeneratedImages. В файле deepzoomproject.xap находится сгенерированное GeneratedImages. В результате, если запустить интернет-магазин и зайти на страницу products/ProductBrowser.aspx, то можно увидеть работающее приложение в действии (рис. 18.9).
(рис 18.9) Работающее Deep Zoom приложение, встроенное в интернет-магазинДанный подход прост, так как не требует написания кода, но в то же время ограничивает разработчика в возможностях. Поэтому создадим через Visual Studio 2008 альтернативную страницу с
Для того чтобы разработать приложение на технологии
(рис 18.10) Добавление в решение нового Silverlight проектаПри добавлении появится окно, представленное на рис. 18.11. Оно позволяет указать, где будет "хоститься" новое приложение, будет ли доступна отладка этого приложения и необходимо ли создавать тестовые страницы.
(рис 18.11) Окно создания нового Silverlight проектаНеобходимости менять заданные по умолчанию значения у нас нет. Можно отказаться от создания тестовых страниц, чтобы не создавать лишних файлов в сайте AWCDShop, тем более что на них может случайно зайти пользователь.
После создания проекта SilverlightDeepZoom ) в сайт будет добавлен файл Silverlight.js, который содержит служебный код, необходимый для работы ClientBin, куда будет помещаться откомпилированное
Наша задача заключается в том, чтобы не только воссоздать приложение, аналогичное по функциональности тому, которое создается Expression Web автоматически, но и расширить его функционал, добавив возможность получать информацию о продукте, если он занимает всю видимую область приложения.
В созданный проект SilverlightDeepZoom будет автоматически добавлена страница MainPage.xaml. Ее код мы доработаем следующим образом:
<UserControl x:Class="SilverlightDeepZoom.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8"/>
<ColumnDefinition Width="64"/>
<ColumnDefinition Width="0.639*"/>
<ColumnDefinition Width="0.361*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="8"/>
<RowDefinition Height="64"/>
<RowDefinition Height="64"/>
<RowDefinition Height="64"/>
<RowDefinition Height="64"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<MultiScaleImage x:Name="ZoomImage" Source="dzc_output.xml" MouseLeftButtonDown="ZoomImage_MouseLeftButtonDown"
MouseLeftButtonUp="ZoomImage_MouseLeftButtonUp"
MouseMove="ZoomImage_MouseMove"
ImageOpenSucceeded="ZoomImage_ImageOpenSucceeded"
MotionFinished="ZoomImage_MotionFinished"
Grid.Row="0" Grid.RowSpan="6" Grid.Column="0"
Grid.ColumnSpan="4"/>
<Image Source="home.png" MouseLeftButtonUp="Home_Click" x:Name='Home'
Grid.Row="1" Grid.Column="1" ></Image>
<Image Source="zoomin.png" MouseLeftButtonUp="ZoomIn_Click" x:Name='ZoomIn'
Grid.Row="2" Grid.Column="1" />
<Image Source="zoomout.png" MouseLeftButtonUp="ZoomOut_Click" x:Name='ZoomOut'
Grid.Row="3" Grid.Column="1"/>
<Rectangle x:Name="InformationPanel" Fill="White" Stroke="Black"
Grid.Column="3" Grid.RowSpan="6" Opacity="0.8" Visibility="Collapsed">
</Rectangle>
<Image x:Name="ProductImage" Margin="2,1,1,1"
Grid.Row="1" Grid.RowSpan="3" Grid.Column="3"/>
</Grid>
</UserControl>
Разберем приведенный выше код. В начале объявляется новый SilverlightDeepZoom.MainPage и установлено шириной в 640 пикселей, а высотой в 480 пикселей. Далее идет определение разметки страницы, состоящей из 4 колонок (2 с фиксированной шириной в 8 и 64 пикселя, а 2 делят оставшееся пространство в отношении примерно 2 к 1) и 6 строк, первые 5 из которых имеют фиксированную высоту. После разметки определяется объект типа MultiScaleImage с именем ZoomImage, который отвечает за отображение Source ) данных для отображения, несколько обработчики событий, а также задано, что компонент располагается в левой верхней ячейке и занимает 6 строк и 4 столбца, то есть весь экран. За компонентом MultiScaleImage следует определение 3 изображений с обработчиками нажатия по ним мышкой.
При этом, так как они определены после MultiScaleImage,
то они будут отображаться поверх него. Далее определена полупрозрачная панель InformationPanel, изначально невидимая и еще одно изображение, которое за счет указанного расположения будет отображаться поверх панели. Так как при этом атрибут Source изображения не указан, то при старте приложения, изображение отображаться не будет.
(рис 18.12) Отображение страницы SilverlightDeepZoom.MainPage в Microsoft Expression BlendТеперь, когда внешний вид приложения разработан, необходимо реализовать логику его работы.
Прежде всего, опишем вспомогательный класс CollectionImage, который будет хранить данные о каждом изображении, используемом в коллаже. Для того чтобы связать объекты этого класса с изображениями, которые будут использоваться в MultiScaleImage, сделаем в классе CollectionImage ссылку MultiScaleSubImage Image, которая будет указывать на соответствующий элемент в коллекции изображений ZoomImage.SubImages. Также в свойствах будет храниться положение изображение, его ширина и высота, порядковый номер и тег.
public class CollectionImage
{
public MultiScaleSubImage Image { get; set; }
public Point Location { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public int ZOrder { get; set; }
public string Tag { get; set; }
}
ZoomImage.SubImages будет пустой.Теперь добавим в класс страницы MainPage в файле MainPage.xaml.cs список CollectionImage, в котором будем хранить все данные об используемых изображениях.
ObservableCollection<CollectionImage> _images = new ObservableCollection<CollectionImage>();
При запуске приложения необходимо заполнить коллекцию _images. Это можно сделать, создав обработчик события ImageOpenSucceeded объекта ZoomImage. Когда это событие срабатывает, коллекция ZoomImage.SubImages уже заполнена, однако объекты типа MultiScaleSubImage не хранят данных, конторе были указаны в поле Tag в Metadata.xml. Так как приложение запускается в браузере на клиенте, а файл хранится на сервере, то мы воспользуемся классом WebClient, метод DownloadStringAsync которого позволяет скачивать файлы с сервера. Когда файл скачен, срабатывает событие DownloadStringCompleted. Определив обработчик этого события, мы сможем разобрать скаченный файл. Так как это XML-файл, то имеет смысл воспользоваться классом XDocument чтобы его разобрать.
private void ZoomImage_ImageOpenSucceeded(object sender, RoutedEventArgs e)
{
duringOpen = true;
WebClient wc = new WebClient();
wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
wc.DownloadStringAsync(new Uri("Metadata.xml", UriKind.Relative));
}
private void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Cancelled == false e.Error == null)
{
string s = e.Result;
XDocument doc = XDocument.Parse(s);
var images = from a in doc.Element("Metadata").Descendants("Image")
select a;
foreach (XElement image in images)
{
CollectionImage ci =
new CollectionImage
{
Height = Convert.ToDouble(image.Element("Height").Value),
Width = Convert.ToDouble(image.Element("Width").Value),
ZOrder = Convert.ToInt32(image.Element("ZOrder").Value) – 1,
Tag = (string) image.Element("Tag").Value,
Location = new Point {X = Convert.ToDouble( image.Element("x").Value),
Y = Convert.ToDouble( image.Element("y").Value)}
}
;
ci.Image = ZoomImage.SubImages[ci.ZOrder];
_images.Add(ci);
}
}
}
Стоит обратить внимание, что значение ZOrder изображений в файле Metadata.xml начинается с 1, в то время, как индекс коллекции ZoomImage.SubImages начинается с 0. Поэтому значение свойства ZOrder объектов CollectionImage будет на 1 меньше, чем то, что указано в файле.
Если сейчас запустить разработанное приложение в тестовой странице, то оно отобразит набор изображений, но работать с ними не получится. Для того чтобы придать приложению интерактивность, определим код обработчиков нажатия на кнопки "Домой", "Приблизить" и "Удалить", обработчиков вращения колесика мышки, а также нажатия левой кнопки мыши и движения курса мыши по приложению.
Полный код этих обработчиков можно посмотреть в приведенном примере, здесь рассмотрим только обработчики нажатия мышью на кнопки "Домой" и "Приблизить".
private void Home_Click(object sender, MouseButtonEventArgs e)
{
InformationPanel.Visibility = Visibility.Collapsed;
ProductImage.Visibility = Visibility.Collapsed;
ZoomImage.ViewportOrigin = new Point(0, 0);
ZoomImage.ViewportWidth = 1;
zoom = 1;
}
private void ZoomIn_Click(object sender, MouseButtonEventArgs e)
{
double newzoom = zoom/1.3;
if (newzoom < minzoom)
{
newzoom = minzoom;
}
Point logicalPoint = ZoomImage.ElementToLogicalPoint(new Point(ActualWidth/2, ActualHeight/2));
ZoomImage.ZoomAboutLogicalPoint(zoom/newzoom, logicalPoint.X, logicalPoint.Y);
zoom = newzoom;
var i = GetIntersectImage();
if (i > 0)
{
InformationPanel.Visibility = System.Windows.Visibility.Visible;
ProductImage.Visibility = System.Windows.Visibility.Visible;
}
else
{
InformationPanel.Visibility = System.Windows.Visibility.Collapsed;
ProductImage.Visibility = System.Windows.Visibility.Collapsed;
}
}
В обработчике Home_Click мы скрываем панель и изображение ProductImage, после чего строкой ZoomImage.ViewportOrigin = new Point(0, 0) устанавливаем верхний левый угол приложения в начальную точку (в случае использования одной картинки – это также ее левый верхний угол), а строкой ZoomImage.ViewportWidth = 1 устанавливаем текущий масштаб так, чтобы отобразилась целиком вся композиция изображений.
ViewportOrigin и ViewportWidth можно по этой ссылке: http://msdn.microsoft.com/en-us/library/system.windows.controls.multiscaleimage.viewportorigin%28VS.95%29.aspxВ обработчике ZoomIn_Click определяется новый масштаб. Далее, при помощи метода ElementToLogicalPoint определяются логические координаты центра приложения, после чего вызывается метод ZoomAboutLogicalPoint, который выполняет изменение масштаба изображения относительно указанной точки. В нашем случае масштаб будет уменьшен в 1.3 раза относительно центра.
Далее вызывается метод GetIntersectImage, который определяет, занимает ли какое-либо изображение все видимое пространство приложения, и если такое изображение найдено, то возвращает его порядковый номер и присваивает ProductImage ссылку на файл, имя которого берется из CollectionImage.Tag, то есть из тэга самого изображения. Если подходящее изображение найдено, необходимо сделать видимыми информационную панель с элементом ProductImage.
Ниже приведен код метода GetIntersectImage:
private int GetIntersectImage()
{
for (int i = 0; i < ZoomImage.SubImages.Count; i++)
{
MultiScaleSubImage subImage = ZoomImage.SubImages[i];
double scaleBy = 1/subImage.ViewportWidth;
Rect rect = new Rect(-subImage.ViewportOrigin.X*scaleBy,
-subImage.ViewportOrigin.Y*scaleBy,
1*scaleBy,
(1/subImage.AspectRatio)*scaleBy);
Point p1 = ZoomImage.ViewportOrigin;
Point p2 = ZoomImage.ElementToLogicalPoint(new Point(ZoomImage.ActualWidth, 0.0));
Point p3 = ZoomImage.ElementToLogicalPoint(new Point(0.0, ZoomImage.ActualHeight));
Point p4 = ZoomImage.ElementToLogicalPoint(new Point(ZoomImage.ActualWidth, ZoomImage.ActualHeight));
if (rect.Contains(p1) rect.Contains(p2) rect.Contains(p3) rect.Contains(p4))
{
BitmapImage bmi = new BitmapImage
(new Uri( "../ProductImages/" +_images[i].Tag+ ".png", UriKind.Relative))
{CreateOptions = BitmapCreateOptions.None};
ProductImage.Source = bmi;
return i;
}
}
return -1;
}
Этот метод в цикле пробегает по всем изображениям из ZoomImage.SubImages и определяет логические координаты вершин, представляя изображение в виде объекта класса Rect. Затем определяются логические координаты вершин приложения, и если все вершины лежат внутри прямоугольника, представляющего изображение, то метод возвращает его номер.
Теперь, когда ProductBrowser2 и добавим на нее следующий код:
<asp:Content ID="Content2" ContentPlaceHolderID="column_l_placeholder" Runat="Server">
<div id="silverlightControlHost">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" style="width: 640px; height: 480px;">
<param name="source" value="../ClientBin/SilverlightDeepZoom.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="3.0.40818.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156v=3.0.40818.0" style="text-decoration:none">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>
</a>
</object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
</asp:Content>
Как и раньше, для того, чтобы установить object. Описание всего кода, кроме параметра source, который указывает на файл ../ClientBin/SilverlightDeepZoom.xap, является стандартным для всех
SilverlightDeepZoom.xap будет автоматически помещен в папку ClientBin. Однако может потребоваться перенести вручную в эту папку файлы ClientBin и все необходимые для работы ресурсы должны располагаться в этой директории (рис. 18.13).
(рис 18.13) Структура директории ClientBinТеперь, если открыть страницу ProductBrowser2 нашего Интернет-магазина (необходимо также доработать мастер страниц, чтобы ввести новый пункт меню), то запустится полноценное
(рис 18.14) Приложение SilverlightDeepZoom в действии
(рис 18.15) Приложение SilverlightDeepZoom в действииТеперь, когда мы научились разрабатывать интерактивные приложения для браузеров, рассмотрим еще одну задачу, которую приходится решать достаточно часто – добавление видеоплеера на страницу.
Предположим, что мы хотим разместить на главной странице видеоролик, который будет проигрываться, когда пользователь зайдет на сайт. Это можно сделать несколькими способами.
Самый простой способ отобразить видеоплеер на странице – воспользоваться
<object type="video/x-ms-wmv" width="200" height="200"> <param name="filename" value ="1.wmv" /> </object>
При этом файл " 1.wmv " должен находиться в корне сайта. Если теперь открыть главную страницу, то на ней сразу же начнется проигрывание видео (рис. 18.16).
(рис 18.16) Проигрывание видео-файла на главной странице сайта при помощи Windows Media Player
Альтернативный вариант заключается в использовании
Проще всего добавить этот плеер через Expression Studio. Для этого необходимо из окна ToolBox перетащить на страницу элемент
(рис 18.17) Добавление Silverlight-плеера на страницу в Microsoft Expression WebПосле того, как разработчик укажет все необходимые данные и нажмет кнопку Encode, Expression Web перекодирует видео и добавит файл в проект, а также создаст silverlightvideos рядом с видео-файлом, и вставит на страницу следующий код:
<div id="silverlightvideocontainer">
<object data="data:application/x-silverlight-2" type="application/x-silverlight-2" width="640" height="352">
<param name="source" value="silverlightvideos/BlackGlassTemplate.xap"/>
<param name="background" value="white" />
<param name="minRuntimeVersion" value="3.0.40624.0" />
<param name="autoUpgrade" value="true" />
<param name="enableHtmlAccess" value="true" />
<param name="enableGPUAcceleration" value="true" />
<param name="initparams" value='playerSettings =
<Playlist>
<AutoLoad>false</AutoLoad>
<AutoPlay>false</AutoPlay>
<DisplayTimeCode>false</DisplayTimeCode>
<EnableCachedComposition>true</EnableCachedComposition>
<EnableCaptions>true</EnableCaptions>
<EnableOffline>true</EnableOffline>
<EnablePopOut>true</EnablePopOut>
<StartMuted>false</StartMuted>
<StretchMode>None</StretchMode>
<Items>
<PlaylistItem>
<AudioCodec>WmaProfessional</AudioCodec>
<Description></Description>
<FileSize>158516095</FileSize>
<FrameRate>23.9759856527702</FrameRate>
<Height>352</Height>
<IsAdaptiveStreaming>false</IsAdaptiveStreaming>
<MediaSource>silverlightvideos/2.wmv</MediaSource>
<ThumbSource></ThumbSource>
<Title></Title>
<VideoCodec>VC1</VideoCodec>
<Width>640</Width>
</PlaylistItem>
</Items>
</Playlist>'/>
<a href="http://go2.microsoft.com/fwlink/?LinkID=124807"
style="text-decoration: none;">
<img src="http://go2.microsoft.com/fwlink/?LinkId=108181"
alt="Get Microsoft Silverlight" style="border-style: none;"/>
</a>
</object>
<iframe id="_sl_historyFrame" style='visibility:hidden;height:0;width:0;border:0px;'>
</iframe>
</div>
В результате на главную страницу будет добавлено
(рис 18.18) Отображение Silverlight-плеера на главной странице сайтаТакой способ позволяет нам отображать заранее заданное видео и имеет следующие преимущества перед обычным плеером:
playlist 'ов;Однако если мы захотим встроить в карточку продукта видеоплеер, который будет отображать видео, связанное с конкретным продуктом, этих возможностей нам не достаточно. Для того чтобы предоставить такую функциональность – разработаем
Добавим в наше решение новый MainPage следующим образом:
<UserControl x:Class="SilverlightPleer.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Width="300" Height="200"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
<Grid x:Name="LayoutRoot" Margin="0,0,0,84">
<Grid.RowDefinitions>
<RowDefinition Height="0.715*"/>
<RowDefinition Height="0.285*"/>
</Grid.RowDefinitions>
<MediaElement x:Name="myMedia" Source="2.wmv" Width="300"
Margin="-2,0,2,-49" d:LayoutOverrides="VerticalAlignment"
Grid.RowSpan="2" AutoPlay="False"/>
<Button Width="94" Height="30" Content="Проиграть" Click="Button_Click"
Margin="-1,0,0,-83" VerticalAlignment="Bottom"
d:LayoutOverrides="VerticalAlignment, Height" RenderTransformOrigin="0.613,1.067"
Grid.Row="1" HorizontalAlignment="Left"/>
<Button Width="92" Height="30" Content="Остановить" Click="Button_Click_1"
HorizontalAlignment="Right" Margin="0,0,0,-83" VerticalAlignment="Bottom"
RenderTransformOrigin="0.613,1.067" Grid.Row="1"
d:LayoutOverrides="VerticalAlignment, Height"/>
<Button Height="30" Content="Пауза" Click="Button_Click_2"
Margin="105,0,103,-82" VerticalAlignment="Bottom"
RenderTransformOrigin="0.613,1.067" Grid.Row="1"
d:LayoutOverrides="VerticalAlignment, Height"/>
</Grid>
</UserControl>
Не будем подробно останавливаться на приведенном коде, отметим только, что на этой странице используется три кнопки и объект MediaElement, который предоставляет интерфейс для отображения различных видео-файлов. Видео-файл указывается в атрибуте Source и должен находиться в директории ClientBin.
Теперь необходимо реализовать логику плеера. Для этого в методе MainPage_Loaded зарегистрируем приложение на странице, чтобы позднее получить доступ к нему через JavaScript, реализуем метод changeMediaSource, который пометим атрибутом [ScriptableMember], что позволит вызывать этот метод из JavaScript. В реализации этого метода остановим проигрывание видео и изменим видео-файл на " 3.wmv " (на самом деле необходимо хранить имя видео-файла для продуктов в БД). Также реализуем обработчики нажатия на кнопки "Проиграть", "Остановить" и "Пауза".
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
HtmlPage.RegisterScriptableObject("basic", this);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
changeMediaSource();
}
[ScriptableMember]
public void changeMediaSource()
{
myMedia.Stop();
myMedia.Source = new Uri("3.wmv", UriKind.Relative);
myMedia.Play();
isStoped = false;
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
myMedia.Stop();
isStoped = true;
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
if (!isStoped)
{
myMedia.Pause();
isStoped = true;
}
else
{
myMedia.Play();
isStoped = false;
}
}
Теперь все готово к тому, чтобы разместить плеер на ASP-компоненте ProductControl. Для этого добавим следующий код:
<div id="silverlightControlHost" style='height:300px; width=200px;'>
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2"
width="100%" height="100%" id="silverlightControl">
<param name="source" value="../ClientBin/SilverlightPleer.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="3.0.40818.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156v=3.0.40818.0"
style="text-decoration:none">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181"
alt="Get Microsoft Silverlight" style="border-style:none"/>
</a>
</object>
<iframe id="_sl_historyFrame"
style="visibility:hidden;height:0px;width:0px;border:0px">
</iframe>
</div>
<asp:Button ID="ButtonPlayJavaScript" runat="server"
Text="Изменить видео" OnClientClick="changeMedia();" />
<script language="javascript" type="text/javascript">
function changeMedia() {
var svlObject = document.getElementById("silverlightControl");
svlObject.Content.basic.changeMediaSource();
}
</script>
Как уже отмечалось, содержимое div 'а стандартно для всех
changeMedia располагается на странице products/default.aspx, в PlaceHolder 'е предназначенном для загрузки скриптов.На рис. 18.19 отображается результирующая карточка продукта со встроенным
(рис 18.19) Карточка продукта со встроенным Silverlight-приложением
Данное практическое занятие рассматривает следующие темы:
Цель практического занятия: Целью данного занятия является знакомство с технологией
Файлы к практическому занятию Вы можете скачать здесь.
Подробно об алгоритмах работы
Один из самых известных примеров использования этой технологии – http://memorabilia.hardrock.com/ (рис. 18.1).
(рис 18.1) Применение технологии Deep Zoom на сайте Hard RockНаша задача – создать аналогичное приложение, в котором пользователь сможет просмотреть имеющиеся в Интернет-магазине велосипеды и узнать какую-либо информацию о выбранном товаре. Для того чтобы сделать подобное приложение, нам понадобится бесплатная программа Microsoft
После запуска программы
(рис 18.2) Импорт изображений в Deep Zoom ComposerНа втором этапе, необходимо из имеющихся изображений скомпоновать коллаж, при этом картинки можно уменьшать и увеличивать в размерах (сохраняя их разрешение), накладывать друг на друга (рис. 18.3).
(рис 18.3) Импорт изображений в Deep Zoom ComposerПомимо этого, на данном шаге можно сделать еще ряд действий, а именно: создать встроенное меню, которое позволит перемещаться от одного изображения к другому; установить ссылки между изображениями друг на друга так, чтобы при щелчке мышкой по одному изображению переходить к связанному; устанавливать внешние ссылки; задавать каждому изображение какое-либо строковое значение, которое потом можно будет использовать.
Меню создается во вкладке "Menu" путем перетаскивания изображений на панель редактирования. При помощи кнопок в верхней части панели можно задавать иерархию пунктов меню (рис. 18.4).
(рис 18.4) Создание меню в Deep Zoom Composer
Для того чтобы задать внутреннюю ссылку, необходимо выделить нужное изображение, вызвать контекстное меню Add Internal Link. Откроется окно со всеми изображениями, с которыми мы можем связать текущее изображение (рис. 18.5).
(рис 18.5) Окно добавления внутренний ссылки в Deep Zoom Composer
Для каждого изображения можно указать тег – строковое значение. Это позволит в дальнейшем идентифицировать выбранное пользователем изображение. Чтобы указать тег, необходимо выбрать изображение и в панель свойство указать нужное значение (рис. 18.6). Для каждого изображения укажем имя файла, в котором оно хранится.
(рис 18.6) Указание тега для изображения в Deep Zoom Composer
После того, как все приготовления сделаны, необходимо экспортировать получившийся коллаж. Это делается на последнем этапе.
(рис 18.7) Экспорт проекта в Deep Zoom ComposerВ результате экспорта будет создана папка, которая будет содержать файл Default.xap, файлы тестовых страниц и папку GeneratedImages. Каталог GeneratedImages в свою очередь состоит из двух каталогов, содержащих части изображений в различных масштабах и нескольких xml файлов. Файл dzc_output.xml описывает созданное Metadata.xml определяет коллекцию изображений и связанные с ними теги.
После того, как приложение разработано, необходимо встроить его в наш Интернет-магазин.
Для того чтобы интегрировать наше приложение в сайт, создадим еще одну страницу на основе мастера страниц master.master – products/ProductBrowser.aspx. Проще всего добавить на эту страницу компонент products/ProductBrowser.aspx в dzc_output.xml.
(рис 18.8) Добавление Deep Zoom на страницу в Microsoft Expression WebВ результате на самой странице будет сгенерирован следующий код:
<asp:Content ID="Content2" ContentPlaceHolderID="column_l_placeholder" runat="Server">
<div id="deepzoomcontainer">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2"
style="width: 640px; height: 480px;">
<param name="source" value="../deepzooms/dzc_output/deepzoomproject.xap" />
<param name="onerror" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="2.0.31005.0" />
<param name="autoUpgrade" value="true" />
<param name="initparams" value="zoomIn=5" />
<a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight"
style="border-style: none;" />
</a>
</object>
<iframe id="I1" style='visibility: hidden; height: 0; width: 0; border: 0px;' name="I1">
</iframe>
</div>
</asp:Content>
При этом в самом проекте будет создан каталог deepzooms, в который будет помещен файл deepzoomproject.xap и скопирована папка GeneratedImages. В файле deepzoomproject.xap находится сгенерированное GeneratedImages. В результате, если запустить интернет-магазин и зайти на страницу products/ProductBrowser.aspx, то можно увидеть работающее приложение в действии (рис. 18.9).
(рис 18.9) Работающее Deep Zoom приложение, встроенное в интернет-магазинДанный подход прост, так как не требует написания кода, но в то же время ограничивает разработчика в возможностях. Поэтому создадим через Visual Studio 2008 альтернативную страницу с
Для того чтобы разработать приложение на технологии
(рис 18.10) Добавление в решение нового Silverlight проектаПри добавлении появится окно, представленное на рис. 18.11. Оно позволяет указать, где будет "хоститься" новое приложение, будет ли доступна отладка этого приложения и необходимо ли создавать тестовые страницы.
(рис 18.11) Окно создания нового Silverlight проектаНеобходимости менять заданные по умолчанию значения у нас нет. Можно отказаться от создания тестовых страниц, чтобы не создавать лишних файлов в сайте AWCDShop, тем более что на них может случайно зайти пользователь.
После создания проекта SilverlightDeepZoom ) в сайт будет добавлен файл Silverlight.js, который содержит служебный код, необходимый для работы ClientBin, куда будет помещаться откомпилированное
Наша задача заключается в том, чтобы не только воссоздать приложение, аналогичное по функциональности тому, которое создается Expression Web автоматически, но и расширить его функционал, добавив возможность получать информацию о продукте, если он занимает всю видимую область приложения.
В созданный проект SilverlightDeepZoom будет автоматически добавлена страница MainPage.xaml. Ее код мы доработаем следующим образом:
<UserControl x:Class="SilverlightDeepZoom.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8"/>
<ColumnDefinition Width="64"/>
<ColumnDefinition Width="0.639*"/>
<ColumnDefinition Width="0.361*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="8"/>
<RowDefinition Height="64"/>
<RowDefinition Height="64"/>
<RowDefinition Height="64"/>
<RowDefinition Height="64"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<MultiScaleImage x:Name="ZoomImage" Source="dzc_output.xml" MouseLeftButtonDown="ZoomImage_MouseLeftButtonDown"
MouseLeftButtonUp="ZoomImage_MouseLeftButtonUp"
MouseMove="ZoomImage_MouseMove"
ImageOpenSucceeded="ZoomImage_ImageOpenSucceeded"
MotionFinished="ZoomImage_MotionFinished"
Grid.Row="0" Grid.RowSpan="6" Grid.Column="0"
Grid.ColumnSpan="4"/>
<Image Source="home.png" MouseLeftButtonUp="Home_Click" x:Name='Home'
Grid.Row="1" Grid.Column="1" ></Image>
<Image Source="zoomin.png" MouseLeftButtonUp="ZoomIn_Click" x:Name='ZoomIn'
Grid.Row="2" Grid.Column="1" />
<Image Source="zoomout.png" MouseLeftButtonUp="ZoomOut_Click" x:Name='ZoomOut'
Grid.Row="3" Grid.Column="1"/>
<Rectangle x:Name="InformationPanel" Fill="White" Stroke="Black"
Grid.Column="3" Grid.RowSpan="6" Opacity="0.8" Visibility="Collapsed">
</Rectangle>
<Image x:Name="ProductImage" Margin="2,1,1,1"
Grid.Row="1" Grid.RowSpan="3" Grid.Column="3"/>
</Grid>
</UserControl>
Разберем приведенный выше код. В начале объявляется новый SilverlightDeepZoom.MainPage и установлено шириной в 640 пикселей, а высотой в 480 пикселей. Далее идет определение разметки страницы, состоящей из 4 колонок (2 с фиксированной шириной в 8 и 64 пикселя, а 2 делят оставшееся пространство в отношении примерно 2 к 1) и 6 строк, первые 5 из которых имеют фиксированную высоту. После разметки определяется объект типа MultiScaleImage с именем ZoomImage, который отвечает за отображение Source ) данных для отображения, несколько обработчики событий, а также задано, что компонент располагается в левой верхней ячейке и занимает 6 строк и 4 столбца, то есть весь экран. За компонентом MultiScaleImage следует определение 3 изображений с обработчиками нажатия по ним мышкой.
При этом, так как они определены после MultiScaleImage,
то они будут отображаться поверх него. Далее определена полупрозрачная панель InformationPanel, изначально невидимая и еще одно изображение, которое за счет указанного расположения будет отображаться поверх панели. Так как при этом атрибут Source изображения не указан, то при старте приложения, изображение отображаться не будет.
(рис 18.12) Отображение страницы SilverlightDeepZoom.MainPage в Microsoft Expression BlendТеперь, когда внешний вид приложения разработан, необходимо реализовать логику его работы.
Прежде всего, опишем вспомогательный класс CollectionImage, который будет хранить данные о каждом изображении, используемом в коллаже. Для того чтобы связать объекты этого класса с изображениями, которые будут использоваться в MultiScaleImage, сделаем в классе CollectionImage ссылку MultiScaleSubImage Image, которая будет указывать на соответствующий элемент в коллекции изображений ZoomImage.SubImages. Также в свойствах будет храниться положение изображение, его ширина и высота, порядковый номер и тег.
public class CollectionImage
{
public MultiScaleSubImage Image { get; set; }
public Point Location { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public int ZOrder { get; set; }
public string Tag { get; set; }
}
ZoomImage.SubImages будет пустой.Теперь добавим в класс страницы MainPage в файле MainPage.xaml.cs список CollectionImage, в котором будем хранить все данные об используемых изображениях.
ObservableCollection<CollectionImage> _images = new ObservableCollection<CollectionImage>();
При запуске приложения необходимо заполнить коллекцию _images. Это можно сделать, создав обработчик события ImageOpenSucceeded объекта ZoomImage. Когда это событие срабатывает, коллекция ZoomImage.SubImages уже заполнена, однако объекты типа MultiScaleSubImage не хранят данных, конторе были указаны в поле Tag в Metadata.xml. Так как приложение запускается в браузере на клиенте, а файл хранится на сервере, то мы воспользуемся классом WebClient, метод DownloadStringAsync которого позволяет скачивать файлы с сервера. Когда файл скачен, срабатывает событие DownloadStringCompleted. Определив обработчик этого события, мы сможем разобрать скаченный файл. Так как это XML-файл, то имеет смысл воспользоваться классом XDocument чтобы его разобрать.
private void ZoomImage_ImageOpenSucceeded(object sender, RoutedEventArgs e)
{
duringOpen = true;
WebClient wc = new WebClient();
wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
wc.DownloadStringAsync(new Uri("Metadata.xml", UriKind.Relative));
}
private void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Cancelled == false e.Error == null)
{
string s = e.Result;
XDocument doc = XDocument.Parse(s);
var images = from a in doc.Element("Metadata").Descendants("Image")
select a;
foreach (XElement image in images)
{
CollectionImage ci =
new CollectionImage
{
Height = Convert.ToDouble(image.Element("Height").Value),
Width = Convert.ToDouble(image.Element("Width").Value),
ZOrder = Convert.ToInt32(image.Element("ZOrder").Value) – 1,
Tag = (string) image.Element("Tag").Value,
Location = new Point {X = Convert.ToDouble( image.Element("x").Value),
Y = Convert.ToDouble( image.Element("y").Value)}
}
;
ci.Image = ZoomImage.SubImages[ci.ZOrder];
_images.Add(ci);
}
}
}
Стоит обратить внимание, что значение ZOrder изображений в файле Metadata.xml начинается с 1, в то время, как индекс коллекции ZoomImage.SubImages начинается с 0. Поэтому значение свойства ZOrder объектов CollectionImage будет на 1 меньше, чем то, что указано в файле.
Если сейчас запустить разработанное приложение в тестовой странице, то оно отобразит набор изображений, но работать с ними не получится. Для того чтобы придать приложению интерактивность, определим код обработчиков нажатия на кнопки "Домой", "Приблизить" и "Удалить", обработчиков вращения колесика мышки, а также нажатия левой кнопки мыши и движения курса мыши по приложению.
Полный код этих обработчиков можно посмотреть в приведенном примере, здесь рассмотрим только обработчики нажатия мышью на кнопки "Домой" и "Приблизить".
private void Home_Click(object sender, MouseButtonEventArgs e)
{
InformationPanel.Visibility = Visibility.Collapsed;
ProductImage.Visibility = Visibility.Collapsed;
ZoomImage.ViewportOrigin = new Point(0, 0);
ZoomImage.ViewportWidth = 1;
zoom = 1;
}
private void ZoomIn_Click(object sender, MouseButtonEventArgs e)
{
double newzoom = zoom/1.3;
if (newzoom < minzoom)
{
newzoom = minzoom;
}
Point logicalPoint = ZoomImage.ElementToLogicalPoint(new Point(ActualWidth/2, ActualHeight/2));
ZoomImage.ZoomAboutLogicalPoint(zoom/newzoom, logicalPoint.X, logicalPoint.Y);
zoom = newzoom;
var i = GetIntersectImage();
if (i > 0)
{
InformationPanel.Visibility = System.Windows.Visibility.Visible;
ProductImage.Visibility = System.Windows.Visibility.Visible;
}
else
{
InformationPanel.Visibility = System.Windows.Visibility.Collapsed;
ProductImage.Visibility = System.Windows.Visibility.Collapsed;
}
}
В обработчике Home_Click мы скрываем панель и изображение ProductImage, после чего строкой ZoomImage.ViewportOrigin = new Point(0, 0) устанавливаем верхний левый угол приложения в начальную точку (в случае использования одной картинки – это также ее левый верхний угол), а строкой ZoomImage.ViewportWidth = 1 устанавливаем текущий масштаб так, чтобы отобразилась целиком вся композиция изображений.
ViewportOrigin и ViewportWidth можно по этой ссылке: http://msdn.microsoft.com/en-us/library/system.windows.controls.multiscaleimage.viewportorigin%28VS.95%29.aspxВ обработчике ZoomIn_Click определяется новый масштаб. Далее, при помощи метода ElementToLogicalPoint определяются логические координаты центра приложения, после чего вызывается метод ZoomAboutLogicalPoint, который выполняет изменение масштаба изображения относительно указанной точки. В нашем случае масштаб будет уменьшен в 1.3 раза относительно центра.
Далее вызывается метод GetIntersectImage, который определяет, занимает ли какое-либо изображение все видимое пространство приложения, и если такое изображение найдено, то возвращает его порядковый номер и присваивает ProductImage ссылку на файл, имя которого берется из CollectionImage.Tag, то есть из тэга самого изображения. Если подходящее изображение найдено, необходимо сделать видимыми информационную панель с элементом ProductImage.
Ниже приведен код метода GetIntersectImage:
private int GetIntersectImage()
{
for (int i = 0; i < ZoomImage.SubImages.Count; i++)
{
MultiScaleSubImage subImage = ZoomImage.SubImages[i];
double scaleBy = 1/subImage.ViewportWidth;
Rect rect = new Rect(-subImage.ViewportOrigin.X*scaleBy,
-subImage.ViewportOrigin.Y*scaleBy,
1*scaleBy,
(1/subImage.AspectRatio)*scaleBy);
Point p1 = ZoomImage.ViewportOrigin;
Point p2 = ZoomImage.ElementToLogicalPoint(new Point(ZoomImage.ActualWidth, 0.0));
Point p3 = ZoomImage.ElementToLogicalPoint(new Point(0.0, ZoomImage.ActualHeight));
Point p4 = ZoomImage.ElementToLogicalPoint(new Point(ZoomImage.ActualWidth, ZoomImage.ActualHeight));
if (rect.Contains(p1) rect.Contains(p2) rect.Contains(p3) rect.Contains(p4))
{
BitmapImage bmi = new BitmapImage
(new Uri( "../ProductImages/" +_images[i].Tag+ ".png", UriKind.Relative))
{CreateOptions = BitmapCreateOptions.None};
ProductImage.Source = bmi;
return i;
}
}
return -1;
}
Этот метод в цикле пробегает по всем изображениям из ZoomImage.SubImages и определяет логические координаты вершин, представляя изображение в виде объекта класса Rect. Затем определяются логические координаты вершин приложения, и если все вершины лежат внутри прямоугольника, представляющего изображение, то метод возвращает его номер.
Теперь, когда ProductBrowser2 и добавим на нее следующий код:
<asp:Content ID="Content2" ContentPlaceHolderID="column_l_placeholder" Runat="Server">
<div id="silverlightControlHost">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" style="width: 640px; height: 480px;">
<param name="source" value="../ClientBin/SilverlightDeepZoom.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="3.0.40818.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156v=3.0.40818.0" style="text-decoration:none">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>
</a>
</object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
</asp:Content>
Как и раньше, для того, чтобы установить object. Описание всего кода, кроме параметра source, который указывает на файл ../ClientBin/SilverlightDeepZoom.xap, является стандартным для всех
SilverlightDeepZoom.xap будет автоматически помещен в папку ClientBin. Однако может потребоваться перенести вручную в эту папку файлы ClientBin и все необходимые для работы ресурсы должны располагаться в этой директории (рис. 18.13).
(рис 18.13) Структура директории ClientBinТеперь, если открыть страницу ProductBrowser2 нашего Интернет-магазина (необходимо также доработать мастер страниц, чтобы ввести новый пункт меню), то запустится полноценное
(рис 18.14) Приложение SilverlightDeepZoom в действии
(рис 18.15) Приложение SilverlightDeepZoom в действииТеперь, когда мы научились разрабатывать интерактивные приложения для браузеров, рассмотрим еще одну задачу, которую приходится решать достаточно часто – добавление видеоплеера на страницу.
Предположим, что мы хотим разместить на главной странице видеоролик, который будет проигрываться, когда пользователь зайдет на сайт. Это можно сделать несколькими способами.
Самый простой способ отобразить видеоплеер на странице – воспользоваться
<object type="video/x-ms-wmv" width="200" height="200"> <param name="filename" value ="1.wmv" /> </object>
При этом файл " 1.wmv " должен находиться в корне сайта. Если теперь открыть главную страницу, то на ней сразу же начнется проигрывание видео (рис. 18.16).
(рис 18.16) Проигрывание видео-файла на главной странице сайта при помощи Windows Media Player
Альтернативный вариант заключается в использовании
Проще всего добавить этот плеер через Expression Studio. Для этого необходимо из окна ToolBox перетащить на страницу элемент
(рис 18.17) Добавление Silverlight-плеера на страницу в Microsoft Expression WebПосле того, как разработчик укажет все необходимые данные и нажмет кнопку Encode, Expression Web перекодирует видео и добавит файл в проект, а также создаст silverlightvideos рядом с видео-файлом, и вставит на страницу следующий код:
<div id="silverlightvideocontainer">
<object data="data:application/x-silverlight-2" type="application/x-silverlight-2" width="640" height="352">
<param name="source" value="silverlightvideos/BlackGlassTemplate.xap"/>
<param name="background" value="white" />
<param name="minRuntimeVersion" value="3.0.40624.0" />
<param name="autoUpgrade" value="true" />
<param name="enableHtmlAccess" value="true" />
<param name="enableGPUAcceleration" value="true" />
<param name="initparams" value='playerSettings =
<Playlist>
<AutoLoad>false</AutoLoad>
<AutoPlay>false</AutoPlay>
<DisplayTimeCode>false</DisplayTimeCode>
<EnableCachedComposition>true</EnableCachedComposition>
<EnableCaptions>true</EnableCaptions>
<EnableOffline>true</EnableOffline>
<EnablePopOut>true</EnablePopOut>
<StartMuted>false</StartMuted>
<StretchMode>None</StretchMode>
<Items>
<PlaylistItem>
<AudioCodec>WmaProfessional</AudioCodec>
<Description></Description>
<FileSize>158516095</FileSize>
<FrameRate>23.9759856527702</FrameRate>
<Height>352</Height>
<IsAdaptiveStreaming>false</IsAdaptiveStreaming>
<MediaSource>silverlightvideos/2.wmv</MediaSource>
<ThumbSource></ThumbSource>
<Title></Title>
<VideoCodec>VC1</VideoCodec>
<Width>640</Width>
</PlaylistItem>
</Items>
</Playlist>'/>
<a href="http://go2.microsoft.com/fwlink/?LinkID=124807"
style="text-decoration: none;">
<img src="http://go2.microsoft.com/fwlink/?LinkId=108181"
alt="Get Microsoft Silverlight" style="border-style: none;"/>
</a>
</object>
<iframe id="_sl_historyFrame" style='visibility:hidden;height:0;width:0;border:0px;'>
</iframe>
</div>
В результате на главную страницу будет добавлено
(рис 18.18) Отображение Silverlight-плеера на главной странице сайтаТакой способ позволяет нам отображать заранее заданное видео и имеет следующие преимущества перед обычным плеером:
playlist 'ов;Однако если мы захотим встроить в карточку продукта видеоплеер, который будет отображать видео, связанное с конкретным продуктом, этих возможностей нам не достаточно. Для того чтобы предоставить такую функциональность – разработаем
Добавим в наше решение новый MainPage следующим образом:
<UserControl x:Class="SilverlightPleer.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Width="300" Height="200"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
<Grid x:Name="LayoutRoot" Margin="0,0,0,84">
<Grid.RowDefinitions>
<RowDefinition Height="0.715*"/>
<RowDefinition Height="0.285*"/>
</Grid.RowDefinitions>
<MediaElement x:Name="myMedia" Source="2.wmv" Width="300"
Margin="-2,0,2,-49" d:LayoutOverrides="VerticalAlignment"
Grid.RowSpan="2" AutoPlay="False"/>
<Button Width="94" Height="30" Content="Проиграть" Click="Button_Click"
Margin="-1,0,0,-83" VerticalAlignment="Bottom"
d:LayoutOverrides="VerticalAlignment, Height" RenderTransformOrigin="0.613,1.067"
Grid.Row="1" HorizontalAlignment="Left"/>
<Button Width="92" Height="30" Content="Остановить" Click="Button_Click_1"
HorizontalAlignment="Right" Margin="0,0,0,-83" VerticalAlignment="Bottom"
RenderTransformOrigin="0.613,1.067" Grid.Row="1"
d:LayoutOverrides="VerticalAlignment, Height"/>
<Button Height="30" Content="Пауза" Click="Button_Click_2"
Margin="105,0,103,-82" VerticalAlignment="Bottom"
RenderTransformOrigin="0.613,1.067" Grid.Row="1"
d:LayoutOverrides="VerticalAlignment, Height"/>
</Grid>
</UserControl>
Не будем подробно останавливаться на приведенном коде, отметим только, что на этой странице используется три кнопки и объект MediaElement, который предоставляет интерфейс для отображения различных видео-файлов. Видео-файл указывается в атрибуте Source и должен находиться в директории ClientBin.
Теперь необходимо реализовать логику плеера. Для этого в методе MainPage_Loaded зарегистрируем приложение на странице, чтобы позднее получить доступ к нему через JavaScript, реализуем метод changeMediaSource, который пометим атрибутом [ScriptableMember], что позволит вызывать этот метод из JavaScript. В реализации этого метода остановим проигрывание видео и изменим видео-файл на " 3.wmv " (на самом деле необходимо хранить имя видео-файла для продуктов в БД). Также реализуем обработчики нажатия на кнопки "Проиграть", "Остановить" и "Пауза".
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
HtmlPage.RegisterScriptableObject("basic", this);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
changeMediaSource();
}
[ScriptableMember]
public void changeMediaSource()
{
myMedia.Stop();
myMedia.Source = new Uri("3.wmv", UriKind.Relative);
myMedia.Play();
isStoped = false;
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
myMedia.Stop();
isStoped = true;
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
if (!isStoped)
{
myMedia.Pause();
isStoped = true;
}
else
{
myMedia.Play();
isStoped = false;
}
}
Теперь все готово к тому, чтобы разместить плеер на ASP-компоненте ProductControl. Для этого добавим следующий код:
<div id="silverlightControlHost" style='height:300px; width=200px;'>
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2"
width="100%" height="100%" id="silverlightControl">
<param name="source" value="../ClientBin/SilverlightPleer.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="3.0.40818.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156v=3.0.40818.0"
style="text-decoration:none">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181"
alt="Get Microsoft Silverlight" style="border-style:none"/>
</a>
</object>
<iframe id="_sl_historyFrame"
style="visibility:hidden;height:0px;width:0px;border:0px">
</iframe>
</div>
<asp:Button ID="ButtonPlayJavaScript" runat="server"
Text="Изменить видео" OnClientClick="changeMedia();" />
<script language="javascript" type="text/javascript">
function changeMedia() {
var svlObject = document.getElementById("silverlightControl");
svlObject.Content.basic.changeMediaSource();
}
</script>
Как уже отмечалось, содержимое div 'а стандартно для всех
changeMedia располагается на странице products/default.aspx, в PlaceHolder 'е предназначенном для загрузки скриптов.На рис. 18.19 отображается результирующая карточка продукта со встроенным
(рис 18.19) Карточка продукта со встроенным Silverlight-приложением
Данное практическое занятие рассматривает следующие темы:
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.