Современные веб-технологии

Применение элементов RIA в Интернет-магазине

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

Цель практического занятия: Целью данного занятия является знакомство с технологией Silverlight.

Файлы к практическому занятию Вы можете скачать здесь.

18.1. Описание Deep Zoom

Deep Zoom представляет собой реализацию технологии Seadragon на платформе .NET. Эта технология позволяет пользователям перетаскивать, приближать и удалять большие изображения (или наборы изображений) в высоком разрешении. Она позволяет сократить время, которое необходимо для первоначального отображения изображения за счет скачивания только видимой его части и уменьшения его разрешения, в зависимости от масштаба. В дальнейшем, остальные части изображения будут скачиваться по мере необходимости. Также, при приближении изображения будет скачиваться более качественная версия картинки, и отображаться пользователю (при этом анимация будет создавать эффект размытости изображения, пока скачивается нужная часть).

Подробно об алгоритмах работы Deep Zoom можно почитать здесь: http://msdn.microsoft.com/en-us/library/cc645050%28VS.95%29.aspx

Один из самых известных примеров использования этой технологии – http://memorabilia.hardrock.com/ (рис. 18.1).

(рис 18.1) Применение технологии Deep Zoom на сайте Hard Rock

Наша задача – создать аналогичное приложение, в котором пользователь сможет просмотреть имеющиеся в Интернет-магазине велосипеды и узнать какую-либо информацию о выбранном товаре. Для того чтобы сделать подобное приложение, нам понадобится бесплатная программа Microsoft Deep Zoom Composer, которую можно скачать по ссылке: http://www.microsoft.com/downloads/details.aspx?FamilyID=457B17B7-52BF-4BDA-87A3-FA8A4673F8BFdisplaylang=en.

18.2. Работа с Deep Zoom Composer

После запуска программы Deep Zoom Composer откроется диалоговое окно, в котором можно выбрать, что мы хотим сделать: создать новый проект или редактировать существующий. При создании нового проекта появляется окно, в котором необходимо указать название проекта, и место на жестком диске, где он будет храниться. Дальнейшая работа с Deep Zoom Composer состоит из трех этапов. На первом этапе, который называется Import, необходимо добавить в проект все изображения, которые будут использоваться при работе приложения. Для добавления изображений можно воспользоваться кнопкой Add Image в правом верхнем углу (рис. 18.2).

(рис 18.2) Импорт изображений в Deep Zoom Composer

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

(рис 18.3) Импорт изображений в Deep Zoom Composer

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

18.2.1. Меню

Меню создается во вкладке "Menu" путем перетаскивания изображений на панель редактирования. При помощи кнопок в верхней части панели можно задавать иерархию пунктов меню (рис. 18.4).

(рис 18.4) Создание меню в Deep Zoom Composer

18.2.2. Внутренние ссылки

Для того чтобы задать внутреннюю ссылку, необходимо выделить нужное изображение, вызвать контекстное меню Add Internal Link. Откроется окно со всеми изображениями, с которыми мы можем связать текущее изображение (рис. 18.5).

(рис 18.5) Окно добавления внутренний ссылки в Deep Zoom Composer

18.2.3. Тэги

Для каждого изображения можно указать тег – строковое значение. Это позволит в дальнейшем идентифицировать выбранное пользователем изображение. Чтобы указать тег, необходимо выбрать изображение и в панель свойство указать нужное значение (рис. 18.6). Для каждого изображения укажем имя файла, в котором оно хранится.

(рис 18.6) Указание тега для изображения в Deep Zoom Composer

18.2.4. Различные способы экспорта из Deep Zoom

После того, как все приготовления сделаны, необходимо экспортировать получившийся коллаж. Это делается на последнем этапе. Deep Zoom Composer по умолчанию предлагает опубликовать коллаж на сервисе DeepZoomPix, что в дальнейшем позволит использовать его на своем сайте или блоге. Однако в данный момент мы воспользуемся альтернативным вариантом, и перейдем к вкладке Custom (рис. 18.7). Здесь необходимо выбрать, в каком виде мы хотим получить результат. Так как мы планируем разрабатывать Deep Zoom приложение, то необходимо выбрать вариант Silverlight Deep Zoom. В поле "Name" нужно указать название приложение, оно может отличаться от имени проекта. Экспортировать изображения можно как единое целое (composition) либо как коллекцию изображений. Нас устраивает второй поход, так как в дальнейшем мы планируем работать с картинками по отдельности, в частности, извлекать их теги.

(рис 18.7) Экспорт проекта в Deep Zoom Composer

В результате экспорта будет создана папка, которая будет содержать файл Silverlight приложения Default.xap, файлы тестовых страниц и папку GeneratedImages. Каталог GeneratedImages в свою очередь состоит из двух каталогов, содержащих части изображений в различных масштабах и нескольких xml файлов. Файл dzc_output.xml описывает созданное Deep Zoom приложение, расположение изображений относительно друг друга, а файл Metadata.xml определяет коллекцию изображений и связанные с ними теги.

После того, как приложение разработано, необходимо встроить его в наш Интернет-магазин.

18.3. Подключение Deep Zoom на страницу через Expression Web

Для того чтобы интегрировать наше приложение в сайт, создадим еще одну страницу на основе мастера страниц master.masterproducts/ProductBrowser.aspx. Проще всего добавить на эту страницу компонент Deep Zoom можно в Microsoft Expression Web. Для этого откроем страницу products/ProductBrowser.aspx в Microsoft Expression Web, во вкладке Toolbox раскроем раздел HTML, а внутри него раскроем подраздел Media (рис. 18.8). Среди представленных элементов будет предлагаться и Deep Zoom. Для того чтобы добавить его, необходимо перетащить иконку элемента на страницу. В открывшемся диалоговом окне необходимо указать путь к файлу 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 находится сгенерированное Silverlight приложение Deep Zoom, которое настроено на работу с данными из папки GeneratedImages. В результате, если запустить интернет-магазин и зайти на страницу products/ProductBrowser.aspx, то можно увидеть работающее приложение в действии (рис. 18.9).

(рис 18.9) Работающее Deep Zoom приложение, встроенное в интернет-магазин

Данный подход прост, так как не требует написания кода, но в то же время ограничивает разработчика в возможностях. Поэтому создадим через Visual Studio 2008 альтернативную страницу с Deep Zoom приложением.

Примечание: для того, чтобы разрабатывать Deep Zoom приложения, необходимо установить следующие компоненты:
  • Microsoft Silverlight 3 SDK –http://www.microsoft.com/downloads/details.aspx?familyid=1EA49236-0DE7-41B1-81C8-A126FF39975Bdisplaylang=en
  • Microsoft Silverlight 3 Tools for Visual Studio 2008 SP1 – http://www.microsoft.com/downloads/details.aspx?familyid=9442B0F2-7465-417A-88F3-5E7B5409E9DDdisplaylang=en
  • 18.4. Интеграция интернет-магазина с Silverlight-приложением

    Для того чтобы разработать приложение на технологии Silverlight откроем сайт в Microsoft Visual Studio 2008 и добавим в решение еще один проект. В качестве шаблона выберем Silverlight Application в разделе Silverlight как это показано на рис. 18.10.

    (рис 18.10) Добавление в решение нового Silverlight проекта

    При добавлении появится окно, представленное на рис. 18.11. Оно позволяет указать, где будет "хоститься" новое приложение, будет ли доступна отладка этого приложения и необходимо ли создавать тестовые страницы.

    (рис 18.11) Окно создания нового Silverlight проекта

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

    После создания проекта Silverlight -приложения (в дальнейшем – SilverlightDeepZoom ) в сайт будет добавлен файл Silverlight.js, который содержит служебный код, необходимый для работы Silverlight, а также папка ClientBin, куда будет помещаться откомпилированное Silverlight приложение и все необходимые для его работы ресурсы.

    Наша задача заключается в том, чтобы не только воссоздать приложение, аналогичное по функциональности тому, которое создается Expression Web автоматически, но и расширить его функционал, добавив возможность получать информацию о продукте, если он занимает всю видимую область приложения.

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

    18.4.1. Разработка пользовательского компонента на основе MultiScaleImage

    В созданный проект 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>

    Разберем приведенный выше код. В начале объявляется новый Silverlight компонент, с названием SilverlightDeepZoom.MainPage и установлено шириной в 640 пикселей, а высотой в 480 пикселей. Далее идет определение разметки страницы, состоящей из 4 колонок (2 с фиксированной шириной в 8 и 64 пикселя, а 2 делят оставшееся пространство в отношении примерно 2 к 1) и 6 строк, первые 5 из которых имеют фиксированную высоту. После разметки определяется объект типа MultiScaleImage с именем ZoomImage, который отвечает за отображение Deep Zoom. В атрибутах указан источник ( Source ) данных для отображения, несколько обработчики событий, а также задано, что компонент располагается в левой верхней ячейке и занимает 6 строк и 4 столбца, то есть весь экран. За компонентом MultiScaleImage следует определение 3 изображений с обработчиками нажатия по ним мышкой. При этом, так как они определены после MultiScaleImage, то они будут отображаться поверх него. Далее определена полупрозрачная панель InformationPanel, изначально невидимая и еще одно изображение, которое за счет указанного расположения будет отображаться поверх панели. Так как при этом атрибут Source изображения не указан, то при старте приложения, изображение отображаться не будет.

    Примечание: создавать сложный дизайн приложений вручную, набирая XAML-код неудобно. Для этих целей используется продукт Microsoft Expression Blend, который позволяет визуально редактировать WPF и Silverlight интерфейсы. Разработанный компонент в Expression Blend будет выглядеть так, как представлено на рис. 18.12. Подробнее ознакомиться с продуктом Microsoft Expression Blend можно по этой ссылке: http://blogs.msdn.com/expression/. (рис 18.12) Отображение страницы SilverlightDeepZoom.MainPage в Microsoft Expression Blend

    Теперь, когда внешний вид приложения разработан, необходимо реализовать логику его работы.

    18.4.2. Работа с изображениями

    Прежде всего, опишем вспомогательный класс 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; }
        }
    Примечание: если во время работы Deep Zoom Composer на этапе экспорта был выбран вариант экспорта в виде одного изображения то коллекция ZoomImage.SubImages будет пустой.

    Теперь добавим в класс страницы MainPage в файле MainPage.xaml.cs список CollectionImage, в котором будем хранить все данные об используемых изображениях.

    ObservableCollection<CollectionImage> _images = new ObservableCollection<CollectionImage>();

    При запуске приложения необходимо заполнить коллекцию _images. Это можно сделать, создав обработчик события ImageOpenSucceeded объекта ZoomImage. Когда это событие срабатывает, коллекция ZoomImage.SubImages уже заполнена, однако объекты типа MultiScaleSubImage не хранят данных, конторе были указаны в поле Tag в Deep Zoom Composer. Для того чтобы их загрузить необходимо прочитать сгенерированный файл 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 меньше, чем то, что указано в файле.

    18.4.3. Отображение

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

    Полный код этих обработчиков можно посмотреть в приведенном примере, здесь рассмотрим только обработчики нажатия мышью на кнопки "Домой" и "Приблизить".

    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. Затем определяются логические координаты вершин приложения, и если все вершины лежат внутри прямоугольника, представляющего изображение, то метод возвращает его номер.

    18.4.4. Установка приложения Silverlight на страницу

    Теперь, когда Silverlight -приложение разработано, необходимо добавит его в ASP-сайт. Для этого создадим страницу 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>

    Как и раньше, для того, чтобы установить Silverlight на страницу используется тег object. Описание всего кода, кроме параметра source, который указывает на файл ../ClientBin/SilverlightDeepZoom.xap, является стандартным для всех Silverlight -приложений.

    Примечание: при компиляции проектов, файл SilverlightDeepZoom.xap будет автоматически помещен в папку ClientBin. Однако может потребоваться перенести вручную в эту папку файлы Deep Zoom, иначе приложение не будет работать. В отличие от всего сайта, для которого каталог, в котором располагается сайт, является корневым, для Silverlight -приложения корневой является директория ClientBin и все необходимые для работы ресурсы должны располагаться в этой директории (рис. 18.13). (рис 18.13) Структура директории ClientBin

    Теперь, если открыть страницу ProductBrowser2 нашего Интернет-магазина (необходимо также доработать мастер страниц, чтобы ввести новый пункт меню), то запустится полноценное Silverlight -приложение, как на рис. 18.14 и рис. 18.15.

    (рис 18.14) Приложение SilverlightDeepZoom в действии(рис 18.15) Приложение SilverlightDeepZoom в действии

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

    18.5. Способы подключения видео

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

    18.5.1. Использование Windows Media Player

    Самый простой способ отобразить видеоплеер на странице – воспользоваться Windows Media Player. Для этого на главную страницу достаточно добавить следующий код:

    <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

    18.5.2. Использование Silverlight-плеера

    Альтернативный вариант заключается в использовании Silverlight -плеера.

    Проще всего добавить этот плеер через Expression Studio. Для этого необходимо из окна ToolBox перетащить на страницу элемент Silverlight Video. В появившемся диалоговом окне необходимо указать видео-файл, который надо отобразить, после чего откроется еще одно диалоговое окно, изображенное на рис. 18.17. Оно позволяет перекодировать видео в нужную кодировку, указать шаблон плеера, а также указать ряд параметров (например, нужно ли начинать проигрывать видео сразу после открытия страницы, включать ли по умолчанию звук и другие).

    (рис 18.17) Добавление Silverlight-плеера на страницу в Microsoft Expression Web

    После того, как разработчик укажет все необходимые данные и нажмет кнопку Encode, Expression Web перекодирует видео и добавит файл в проект, а также создаст Silverlight -приложение, поместив его по умолчанию в директорию 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>
    Примечание: создать Silverlight -плеер и перекодировать видео можно также в Microsoft Expression Encoder.

    В результате на главную страницу будет добавлено Silverlight -приложение, позволяющее проигрывать видео (рис. 18.18).

    (рис 18.18) Отображение Silverlight-плеера на главной странице сайта

    Такой способ позволяет нам отображать заранее заданное видео и имеет следующие преимущества перед обычным плеером:

  • возможность настройки дизайна плеера;
  • возможность создания playlist 'ов;
  • возможность проигрывать различные форматы видео;
  • возможность навигации по видео, в том числе распознавать и переходить к заранее отмеченным на видео моментам.
  • Однако если мы захотим встроить в карточку продукта видеоплеер, который будет отображать видео, связанное с конкретным продуктом, этих возможностей нам не достаточно. Для того чтобы предоставить такую функциональность – разработаем Silverlight -приложение, аналогичное тому, что мы создали для Deep Zoom.

    18.5.3. Разработка Silverlight-плеера с динамическим контентом

    Добавим в наше решение новый Silverlight проект SilverlightPleer и реализуем класс 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 'а стандартно для всех Silverlight -приложений. Помимо этого, добавляется новая Javascript-функция, которая также позволяет менять источник видео.

    Примечание: код функции changeMedia располагается на странице products/default.aspx, в PlaceHolder 'е предназначенном для загрузки скриптов.

    На рис. 18.19 отображается результирующая карточка продукта со встроенным Silverlight -приложением.

    (рис 18.19) Карточка продукта со встроенным Silverlight-приложением

    18.6. Ключевые термины

    Deep Zoom, Deep Zoom Composer, Microsoft Expression Web, Silverlight, Microsoft Visual Studio, Windows Media Player.

    18.7. Краткие итоги

    Данное практическое занятие рассматривает следующие темы:

  • Введение в технологию Silverlight ;
  • Описание технологии Deep Zoom ;
  • Работа с Deep Zoom Composer:
  • Импорт изображений в Deep Zoom Composer ;
  • Создание меню в Deep Zoom Composer ;
  • Экспорт из Deep Zoom Composer ;
  • Добавление внутренних ссылок и тегов в Deep Zoom Composer ;
  • Подключение Deep Zoom на страницу через Expression Web;
  • Интеграция Silverlight -приложения в Интернет-магазин через Microsoft Visual Studio 2008:
  • Разработка пользовательского компонента на основе MultiScaleImage;
  • Работа с изображениями;
  • Отображение;
  • Установка приложения Silverlight на страницу;
  • Интеграция видеопроигрывателя в Интернет-магазин;
  • Проигрывание видео-файла при помощи Windows Media Player ;
  • Добавление Silverlight -плеера на страницу в Microsoft Expression Web ;
  • Разработка Silverlight -плеера с динамическим контентом.
  • Страницы:

    Цель практического занятия: Целью данного занятия является знакомство с технологией Silverlight.

    Файлы к практическому занятию Вы можете скачать здесь.

    18.1. Описание Deep Zoom

    Deep Zoom представляет собой реализацию технологии Seadragon на платформе .NET. Эта технология позволяет пользователям перетаскивать, приближать и удалять большие изображения (или наборы изображений) в высоком разрешении. Она позволяет сократить время, которое необходимо для первоначального отображения изображения за счет скачивания только видимой его части и уменьшения его разрешения, в зависимости от масштаба. В дальнейшем, остальные части изображения будут скачиваться по мере необходимости. Также, при приближении изображения будет скачиваться более качественная версия картинки, и отображаться пользователю (при этом анимация будет создавать эффект размытости изображения, пока скачивается нужная часть).

    Подробно об алгоритмах работы Deep Zoom можно почитать здесь: http://msdn.microsoft.com/en-us/library/cc645050%28VS.95%29.aspx

    Один из самых известных примеров использования этой технологии – http://memorabilia.hardrock.com/ (рис. 18.1).

    (рис 18.1) Применение технологии Deep Zoom на сайте Hard Rock

    Наша задача – создать аналогичное приложение, в котором пользователь сможет просмотреть имеющиеся в Интернет-магазине велосипеды и узнать какую-либо информацию о выбранном товаре. Для того чтобы сделать подобное приложение, нам понадобится бесплатная программа Microsoft Deep Zoom Composer, которую можно скачать по ссылке: http://www.microsoft.com/downloads/details.aspx?FamilyID=457B17B7-52BF-4BDA-87A3-FA8A4673F8BFdisplaylang=en.

    18.2. Работа с Deep Zoom Composer

    После запуска программы Deep Zoom Composer откроется диалоговое окно, в котором можно выбрать, что мы хотим сделать: создать новый проект или редактировать существующий. При создании нового проекта появляется окно, в котором необходимо указать название проекта, и место на жестком диске, где он будет храниться. Дальнейшая работа с Deep Zoom Composer состоит из трех этапов. На первом этапе, который называется Import, необходимо добавить в проект все изображения, которые будут использоваться при работе приложения. Для добавления изображений можно воспользоваться кнопкой Add Image в правом верхнем углу (рис. 18.2).

    (рис 18.2) Импорт изображений в Deep Zoom Composer

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

    (рис 18.3) Импорт изображений в Deep Zoom Composer

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

    18.2.1. Меню

    Меню создается во вкладке "Menu" путем перетаскивания изображений на панель редактирования. При помощи кнопок в верхней части панели можно задавать иерархию пунктов меню (рис. 18.4).

    (рис 18.4) Создание меню в Deep Zoom Composer

    18.2.2. Внутренние ссылки

    Для того чтобы задать внутреннюю ссылку, необходимо выделить нужное изображение, вызвать контекстное меню Add Internal Link. Откроется окно со всеми изображениями, с которыми мы можем связать текущее изображение (рис. 18.5).

    (рис 18.5) Окно добавления внутренний ссылки в Deep Zoom Composer

    18.2.3. Тэги

    Для каждого изображения можно указать тег – строковое значение. Это позволит в дальнейшем идентифицировать выбранное пользователем изображение. Чтобы указать тег, необходимо выбрать изображение и в панель свойство указать нужное значение (рис. 18.6). Для каждого изображения укажем имя файла, в котором оно хранится.

    (рис 18.6) Указание тега для изображения в Deep Zoom Composer

    18.2.4. Различные способы экспорта из Deep Zoom

    После того, как все приготовления сделаны, необходимо экспортировать получившийся коллаж. Это делается на последнем этапе. Deep Zoom Composer по умолчанию предлагает опубликовать коллаж на сервисе DeepZoomPix, что в дальнейшем позволит использовать его на своем сайте или блоге. Однако в данный момент мы воспользуемся альтернативным вариантом, и перейдем к вкладке Custom (рис. 18.7). Здесь необходимо выбрать, в каком виде мы хотим получить результат. Так как мы планируем разрабатывать Deep Zoom приложение, то необходимо выбрать вариант Silverlight Deep Zoom. В поле "Name" нужно указать название приложение, оно может отличаться от имени проекта. Экспортировать изображения можно как единое целое (composition) либо как коллекцию изображений. Нас устраивает второй поход, так как в дальнейшем мы планируем работать с картинками по отдельности, в частности, извлекать их теги.

    (рис 18.7) Экспорт проекта в Deep Zoom Composer

    В результате экспорта будет создана папка, которая будет содержать файл Silverlight приложения Default.xap, файлы тестовых страниц и папку GeneratedImages. Каталог GeneratedImages в свою очередь состоит из двух каталогов, содержащих части изображений в различных масштабах и нескольких xml файлов. Файл dzc_output.xml описывает созданное Deep Zoom приложение, расположение изображений относительно друг друга, а файл Metadata.xml определяет коллекцию изображений и связанные с ними теги.

    После того, как приложение разработано, необходимо встроить его в наш Интернет-магазин.

    18.3. Подключение Deep Zoom на страницу через Expression Web

    Для того чтобы интегрировать наше приложение в сайт, создадим еще одну страницу на основе мастера страниц master.masterproducts/ProductBrowser.aspx. Проще всего добавить на эту страницу компонент Deep Zoom можно в Microsoft Expression Web. Для этого откроем страницу products/ProductBrowser.aspx в Microsoft Expression Web, во вкладке Toolbox раскроем раздел HTML, а внутри него раскроем подраздел Media (рис. 18.8). Среди представленных элементов будет предлагаться и Deep Zoom. Для того чтобы добавить его, необходимо перетащить иконку элемента на страницу. В открывшемся диалоговом окне необходимо указать путь к файлу 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 находится сгенерированное Silverlight приложение Deep Zoom, которое настроено на работу с данными из папки GeneratedImages. В результате, если запустить интернет-магазин и зайти на страницу products/ProductBrowser.aspx, то можно увидеть работающее приложение в действии (рис. 18.9).

    (рис 18.9) Работающее Deep Zoom приложение, встроенное в интернет-магазин

    Данный подход прост, так как не требует написания кода, но в то же время ограничивает разработчика в возможностях. Поэтому создадим через Visual Studio 2008 альтернативную страницу с Deep Zoom приложением.

    Примечание: для того, чтобы разрабатывать Deep Zoom приложения, необходимо установить следующие компоненты:
  • Microsoft Silverlight 3 SDK –http://www.microsoft.com/downloads/details.aspx?familyid=1EA49236-0DE7-41B1-81C8-A126FF39975Bdisplaylang=en
  • Microsoft Silverlight 3 Tools for Visual Studio 2008 SP1 – http://www.microsoft.com/downloads/details.aspx?familyid=9442B0F2-7465-417A-88F3-5E7B5409E9DDdisplaylang=en
  • 18.4. Интеграция интернет-магазина с Silverlight-приложением

    Для того чтобы разработать приложение на технологии Silverlight откроем сайт в Microsoft Visual Studio 2008 и добавим в решение еще один проект. В качестве шаблона выберем Silverlight Application в разделе Silverlight как это показано на рис. 18.10.

    (рис 18.10) Добавление в решение нового Silverlight проекта

    При добавлении появится окно, представленное на рис. 18.11. Оно позволяет указать, где будет "хоститься" новое приложение, будет ли доступна отладка этого приложения и необходимо ли создавать тестовые страницы.

    (рис 18.11) Окно создания нового Silverlight проекта

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

    После создания проекта Silverlight -приложения (в дальнейшем – SilverlightDeepZoom ) в сайт будет добавлен файл Silverlight.js, который содержит служебный код, необходимый для работы Silverlight, а также папка ClientBin, куда будет помещаться откомпилированное Silverlight приложение и все необходимые для его работы ресурсы.

    Наша задача заключается в том, чтобы не только воссоздать приложение, аналогичное по функциональности тому, которое создается Expression Web автоматически, но и расширить его функционал, добавив возможность получать информацию о продукте, если он занимает всю видимую область приложения.

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

    18.4.1. Разработка пользовательского компонента на основе MultiScaleImage

    В созданный проект 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>

    Разберем приведенный выше код. В начале объявляется новый Silverlight компонент, с названием SilverlightDeepZoom.MainPage и установлено шириной в 640 пикселей, а высотой в 480 пикселей. Далее идет определение разметки страницы, состоящей из 4 колонок (2 с фиксированной шириной в 8 и 64 пикселя, а 2 делят оставшееся пространство в отношении примерно 2 к 1) и 6 строк, первые 5 из которых имеют фиксированную высоту. После разметки определяется объект типа MultiScaleImage с именем ZoomImage, который отвечает за отображение Deep Zoom. В атрибутах указан источник ( Source ) данных для отображения, несколько обработчики событий, а также задано, что компонент располагается в левой верхней ячейке и занимает 6 строк и 4 столбца, то есть весь экран. За компонентом MultiScaleImage следует определение 3 изображений с обработчиками нажатия по ним мышкой. При этом, так как они определены после MultiScaleImage, то они будут отображаться поверх него. Далее определена полупрозрачная панель InformationPanel, изначально невидимая и еще одно изображение, которое за счет указанного расположения будет отображаться поверх панели. Так как при этом атрибут Source изображения не указан, то при старте приложения, изображение отображаться не будет.

    Примечание: создавать сложный дизайн приложений вручную, набирая XAML-код неудобно. Для этих целей используется продукт Microsoft Expression Blend, который позволяет визуально редактировать WPF и Silverlight интерфейсы. Разработанный компонент в Expression Blend будет выглядеть так, как представлено на рис. 18.12. Подробнее ознакомиться с продуктом Microsoft Expression Blend можно по этой ссылке: http://blogs.msdn.com/expression/. (рис 18.12) Отображение страницы SilverlightDeepZoom.MainPage в Microsoft Expression Blend

    Теперь, когда внешний вид приложения разработан, необходимо реализовать логику его работы.

    18.4.2. Работа с изображениями

    Прежде всего, опишем вспомогательный класс 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; }
        }
    Примечание: если во время работы Deep Zoom Composer на этапе экспорта был выбран вариант экспорта в виде одного изображения то коллекция ZoomImage.SubImages будет пустой.

    Теперь добавим в класс страницы MainPage в файле MainPage.xaml.cs список CollectionImage, в котором будем хранить все данные об используемых изображениях.

    ObservableCollection<CollectionImage> _images = new ObservableCollection<CollectionImage>();

    При запуске приложения необходимо заполнить коллекцию _images. Это можно сделать, создав обработчик события ImageOpenSucceeded объекта ZoomImage. Когда это событие срабатывает, коллекция ZoomImage.SubImages уже заполнена, однако объекты типа MultiScaleSubImage не хранят данных, конторе были указаны в поле Tag в Deep Zoom Composer. Для того чтобы их загрузить необходимо прочитать сгенерированный файл 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 меньше, чем то, что указано в файле.

    18.4.3. Отображение

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

    Полный код этих обработчиков можно посмотреть в приведенном примере, здесь рассмотрим только обработчики нажатия мышью на кнопки "Домой" и "Приблизить".

    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. Затем определяются логические координаты вершин приложения, и если все вершины лежат внутри прямоугольника, представляющего изображение, то метод возвращает его номер.

    18.4.4. Установка приложения Silverlight на страницу

    Теперь, когда Silverlight -приложение разработано, необходимо добавит его в ASP-сайт. Для этого создадим страницу 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>

    Как и раньше, для того, чтобы установить Silverlight на страницу используется тег object. Описание всего кода, кроме параметра source, который указывает на файл ../ClientBin/SilverlightDeepZoom.xap, является стандартным для всех Silverlight -приложений.

    Примечание: при компиляции проектов, файл SilverlightDeepZoom.xap будет автоматически помещен в папку ClientBin. Однако может потребоваться перенести вручную в эту папку файлы Deep Zoom, иначе приложение не будет работать. В отличие от всего сайта, для которого каталог, в котором располагается сайт, является корневым, для Silverlight -приложения корневой является директория ClientBin и все необходимые для работы ресурсы должны располагаться в этой директории (рис. 18.13). (рис 18.13) Структура директории ClientBin

    Теперь, если открыть страницу ProductBrowser2 нашего Интернет-магазина (необходимо также доработать мастер страниц, чтобы ввести новый пункт меню), то запустится полноценное Silverlight -приложение, как на рис. 18.14 и рис. 18.15.

    (рис 18.14) Приложение SilverlightDeepZoom в действии(рис 18.15) Приложение SilverlightDeepZoom в действии

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

    18.5. Способы подключения видео

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

    18.5.1. Использование Windows Media Player

    Самый простой способ отобразить видеоплеер на странице – воспользоваться Windows Media Player. Для этого на главную страницу достаточно добавить следующий код:

    <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

    18.5.2. Использование Silverlight-плеера

    Альтернативный вариант заключается в использовании Silverlight -плеера.

    Проще всего добавить этот плеер через Expression Studio. Для этого необходимо из окна ToolBox перетащить на страницу элемент Silverlight Video. В появившемся диалоговом окне необходимо указать видео-файл, который надо отобразить, после чего откроется еще одно диалоговое окно, изображенное на рис. 18.17. Оно позволяет перекодировать видео в нужную кодировку, указать шаблон плеера, а также указать ряд параметров (например, нужно ли начинать проигрывать видео сразу после открытия страницы, включать ли по умолчанию звук и другие).

    (рис 18.17) Добавление Silverlight-плеера на страницу в Microsoft Expression Web

    После того, как разработчик укажет все необходимые данные и нажмет кнопку Encode, Expression Web перекодирует видео и добавит файл в проект, а также создаст Silverlight -приложение, поместив его по умолчанию в директорию 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>
    Примечание: создать Silverlight -плеер и перекодировать видео можно также в Microsoft Expression Encoder.

    В результате на главную страницу будет добавлено Silverlight -приложение, позволяющее проигрывать видео (рис. 18.18).

    (рис 18.18) Отображение Silverlight-плеера на главной странице сайта

    Такой способ позволяет нам отображать заранее заданное видео и имеет следующие преимущества перед обычным плеером:

  • возможность настройки дизайна плеера;
  • возможность создания playlist 'ов;
  • возможность проигрывать различные форматы видео;
  • возможность навигации по видео, в том числе распознавать и переходить к заранее отмеченным на видео моментам.
  • Однако если мы захотим встроить в карточку продукта видеоплеер, который будет отображать видео, связанное с конкретным продуктом, этих возможностей нам не достаточно. Для того чтобы предоставить такую функциональность – разработаем Silverlight -приложение, аналогичное тому, что мы создали для Deep Zoom.

    18.5.3. Разработка Silverlight-плеера с динамическим контентом

    Добавим в наше решение новый Silverlight проект SilverlightPleer и реализуем класс 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 'а стандартно для всех Silverlight -приложений. Помимо этого, добавляется новая Javascript-функция, которая также позволяет менять источник видео.

    Примечание: код функции changeMedia располагается на странице products/default.aspx, в PlaceHolder 'е предназначенном для загрузки скриптов.

    На рис. 18.19 отображается результирующая карточка продукта со встроенным Silverlight -приложением.

    (рис 18.19) Карточка продукта со встроенным Silverlight-приложением

    18.6. Ключевые термины

    Deep Zoom, Deep Zoom Composer, Microsoft Expression Web, Silverlight, Microsoft Visual Studio, Windows Media Player.

    18.7. Краткие итоги

    Данное практическое занятие рассматривает следующие темы:

  • Введение в технологию Silverlight ;
  • Описание технологии Deep Zoom ;
  • Работа с Deep Zoom Composer:
  • Импорт изображений в Deep Zoom Composer ;
  • Создание меню в Deep Zoom Composer ;
  • Экспорт из Deep Zoom Composer ;
  • Добавление внутренних ссылок и тегов в Deep Zoom Composer ;
  • Подключение Deep Zoom на страницу через Expression Web;
  • Интеграция Silverlight -приложения в Интернет-магазин через Microsoft Visual Studio 2008:
  • Разработка пользовательского компонента на основе MultiScaleImage;
  • Работа с изображениями;
  • Отображение;
  • Установка приложения Silverlight на страницу;
  • Интеграция видеопроигрывателя в Интернет-магазин;
  • Проигрывание видео-файла при помощи Windows Media Player ;
  • Добавление Silverlight -плеера на страницу в Microsoft Expression Web ;
  • Разработка Silverlight -плеера с динамическим контентом.
  • Вернуться к учебному плану