Теория и практика разработки современных клиентских веб-приложений

Разработка приложений на Silverlight

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

Задание 1. Создание простого Silverlight -приложения в Microsoft Visual Web Developer 2008 Express.

1) С помощью раздела меню File -> New Project (или комбинации <Ctrl>+<Shift>+<N> ) необходимо открыть окно для выбора шаблона проекта.

(рис 23.1) Создание нового Silverlight проекта

В списке проектов для Silverlight будут доступны шаблоны Silverlight Application (приложение Silverlight ), Silverlight Navigation Application (приложение Silverlight с поддержкой навигации) и Silverlight Class Library (библиотека классов Silverlight ). Необходимо выбрать шаблон Silverlight Application, задать имя и местоположение нового проекта. После нажатия OK будет запущен New Silverlight Application Wizard (Мастер нового приложения Silverlight ).

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

(рис 23.2) Выбор типа Silverlight приложения

Необходимо выбрать вариант ASP.NET Web Site и создать проект.

(рис 23.3) Вид нового Silverlight проекта в VWDE

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

(рис 23.4) Структура нового Silverlight проекта

Как видно из рисунка, проект содержит два решения: базовый элемент управления Silverlight (SilverlighApplicationStart) и веб-приложение (SilverlighApplicationStart.Web) . Созданный шаблоном базовый проект содержит ряд файлов, включая манифест приложения AppManifest.xml, XAML -файл приложения App.xaml с файлом выделенного кода App.xaml.cs, страницу-пример Default.aspx с файлом выделенного кода Default.aspx.cs, информационный файл сборки AssemblyInfo.cs и некоторые ссылки.

AppManifest.xml создается при компиляции проекта. Если проект имеет какие-либо зависимости во время выполнения, например, внешние элементы управления, то ссылки на них размещаются в этом файле.

Файл Assemblyinfo.cs содержит метаданные, которые должны быть скомпилированы в DLL.

Папка References содержит ссылки на ряд сборок. Это основные сборки Silverlight, которые необходимы для запуска приложения.

  • Mscorlib - В сборку входят основные типы, используемые приложениями Silverlight.
  • System - В сборку входят многие высокоуровневые типы, используемые для разработки и отладки приложений Silverlight, такие как компилятор и классы для отладки и диагностики.
  • System.Core - Сборка включает основные элементы управления и классы Silverlight.
  • System.Net - Сборка включает библиотеки .NET, необходимые для сетевого взаимодействия.
  • System.Xml - В сборку входят библиотеки Silverlight для обработки XML.
  • System.Windows - В сборку входят основные функциональные возможности Windows и Silverlight, включая элементы управления Silverlight.
  • System.Windows.Browser - В сборку входят библиотеки, используемые для взаимодействия с браузером.
  • Файл App.xaml создается интегрированной средой разработки при создании проекта Silverlight по шаблону. Обычно он используется для хранения общей информации всего приложения. App.xaml содержит объявления, определяющие поведение приложения.

    <Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
                 x:Class="SilverlightApplicationStart.App"
                 >
        <Application.Resources>
            
        </Application.Resources>
    </Application>

    Атрибут x:Class определяет имя класса, в который будет скомпилирован этот XAML файл и связанный с ним файл выделенного кода App.xaml.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    namespace SilverlightApplicationStart
    {
        public partial class App : Application
        {
    
            public App()
            {
                this.Startup += this.Application_Startup;
                this.Exit += this.Application_Exit;
                this.UnhandledException += this.Application_UnhandledException;
    
                InitializeComponent();
            }
    
            private void Application_Startup(object sender, StartupEventArgs e)
            {
                this.RootVisual = new MainPage();
            }
    
            private void Application_Exit(object sender, EventArgs e)
            {
    
            }
            private void Application_UnhandledException(object sender, 
            ApplicationUnhandledExceptionEventArgs e)
            {
                // If the app is running outside of the debugger then report the exception using
                // the browser's exception mechanism. On IE this will display it a yellow alert 
                // icon in the status bar and Firefox will display a script error.
                if (!System.Diagnostics.Debugger.IsAttached)
                {
    
                    // NOTE: This will allow the application to continue running 
                    after an exception has been thrown
                    // but not handled. 
                    // For production applications this error handling should 
                    be replaced with something that will 
                    // report the error to the website and stop the application.
                    e.Handled = true;
                    Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
                }
            }
            private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e)
            {
                try
                {
                    string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace;
                    errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n");
    
                    System.Windows.Browser.HtmlPage.Window.Eval("throw new Error
                    (\"Unhandled Error in Silverlight Application " + errorMsg + "\");");
                }
                catch (Exception)
                {
                }
            }
        }
    }

    Конструктор App() используется для подключения методов Application_Startup и Application_Exit.

    Методы Application_Startup и Application_Exit принимают два параметра: объект, формирующий событие, и объект аргументов.

    В методе Application_Startup происходит присвоение свойству RootVisual (Корневой визуальный элемент) приложения нового объекта MainPage (Главная страница). Тем самым объявляется, что UI ( user interface - пользовательский интерфейс) объекта Page является первым экраном UI, который должно создать это приложение. Все другие экраны UI, объявленные в XAML, должны будут запускаться из объекта MainPage. Объект MainPage является XAML -объектом по умолчанию, создаваемым шаблоном для размещения UI приложения.

    Файл MainPage.xaml является для приложения UI по умолчанию. При компиляции вместе с ассоциированным с ним файлом выделенного кода он формирует класс MainPage, экземпляр которого будет объектом MainPage:

    <UserControl x:Class="SilverlightApplicationStart.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>
    </UserControl>

    Контейнером XAML является UserControl. При построении .NET -приложений Silverlight в Visual Studio, фактически, создаются элементы управления, которые компилируются в DLL -файл и помещаются в XAP -файл, который затем открывает и исполняет Silverlight.

    Экземпляр UserControl называется SilverlightApplicationStart.MainPage, где SilverlightApplicationStart - это пространство имен, а MainPage - имя класса из этого пространства имен.

    Объявления xmlns и xmlns:x задают пространство имен по умолчанию и дополнительное пространство имен, которые должны использоваться для проверки корректности XAML.

    Для ширины и высоты заданы значения по умолчанию: 640 ? 480.

    Далее следует корневой элемент Grid. В Silverlight 3 корневым элементом должен быть элемент Container, которым в данном случае является Grid с именем LayoutRoot. Следовательно, все элементы дизайна UI являются дочерними элементами данного узла.

    Рассмотрим выделенный код MainPage.xaml.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    namespace SilverlightApplicationStart
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
            }
        }
    }

    Это описание стандартного класса MainPage, унаследованного от UserControl. В конструкторе класса выполняется общая настройка с помощью вызова метода InitializeComponent().

    В дальнейших примерах именно в этот модуль будет добавляться специфический для веб-приложений код.

    Шаблон помимо проекта элемента управления, создает также веб-проект, в котором размещается Silverlight -приложение. Веб-проект включает два ASPX -файла: Default.aspx, содержащий пустую веб-форму, на базе которой можно построить свое приложение; и тестовую страницу SilverlightApplicationStartTestPage.aspx, которая содержит все необходимое для запуска Silverlight из ASP.NET.

    Хотя Silverlight не имеет никаких зависимостей на стороне сервера, ASP.NET предлагает элементы управления, обеспечивающие возможность создания JavaScript и HTML на стороне клиента, необходимых для размещения Silverlight в браузере.

    2) Создание простейшей сцены.

    Вставьте в файл MainPage.xaml следующий код на языке XAML:

    <UserControl x:Class="SilverlightApplicationStart.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="800" d:DesignHeight="600" >
       
        <Grid x:Name="LayoutRoot" Width="400"
            Height="300"
            Canvas.Left="120"
            Canvas.Top="110"
            Background="Red">
    
            <Rectangle Width="240" 
                 Height="150"
                 Fill="Yellow"
                 Margin="40" 
    Canvas.ZIndex="0"/>
    
            <Ellipse Width="200"
                 Height="140"
                 Fill="#CCFFFFFF"
                 HorizontalAlignment="Right"
                 VerticalAlignment="Bottom"
                 Margin="60" />
            
            <TextBlock Text="Hello world"
                   FontSize="28"
                   Foreground="Blue"
                   Margin="110" >
            </TextBlock>
    
        </Grid>
    </UserControl>

    Сцена содержит 4 объекта: контейнер ( Grid ) красного цвета, желтый прямоугольник ( Rectangle ), белый эллипс ( Ellipse ) с атрибутом прозрачности и текстовый блок ( TextBlock ) голубого цвета.

    После компиляции ( <Ctrl>+<Shift>+<B> ) и запуска ( <Ctrl>+<F5> ) проекта в веб-браузере будет автоматически загружен документ:

    http://localhost:port/SilverlightApplicationStart.Web/SilverlightApplicationStartTestPage.aspx

    следующего вида:

    (рис 23.5) Пример простейшего Silverlight приложения

    Можно теперь разместить полученный контент Silverlight на веб-сервер. Для этого необходимо скопировать целиком папку SilverlightApplicationStart.Web на веб-сервер. В указанном каталоге содержится файл SilverlightApplicationStartTestPage.html, содержащий ссылку на Silverlight ресурс:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" >
    
    <head>
        <title>SilverlightApplicationStart</title>
        <style type="text/css">
        html, body {
    	    height: 100%;
    	    overflow: auto;
        }
        body {
    	    padding: 0;
    	    margin: 0;
        }
        #silverlightControlHost {
    	    height: 100%;
    	    text-align:center;
        }
        </style>
    
        <script type="text/javascript" src="Silverlight.js"></script>
        <script type="text/javascript">
            function onSilverlightError(sender, args) {
                var appSource = "";
                if (sender != null  sender != 0) {
                  appSource = sender.getHost().Source;
                }
                
                var errorType = args.ErrorType;
                var iErrorCode = args.ErrorCode;
    
                if (errorType == "ImageError" || errorType == "MediaError") {
                  return;
                }
    
                var errMsg = "Unhandled Error in Silverlight Application " +  appSource + "\n" ;
    
                errMsg += "Code: "+ iErrorCode + "    \n";
                errMsg += "Category: " + errorType + "       \n";
                errMsg += "Message: " + args.ErrorMessage + "     \n";
    
                if (errorType == "ParserError") {
                    errMsg += "File: " + args.xamlFile + "     \n";
                    errMsg += "Line: " + args.lineNumber + "     \n";
                    errMsg += "Position: " + args.charPosition + "     \n";
                }
                else if (errorType == "RuntimeError") {           
                    if (args.lineNumber != 0) {
                        errMsg += "Line: " + args.lineNumber + "     \n";
                        errMsg += "Position: " +  args.charPosition + "     \n";
                    }
                    errMsg += "MethodName: " + args.methodName + "     \n";
                }
    
                throw new Error(errMsg);
            }
        </script>
    </head>
    
    <body>
        <form id="form1" runat="server" style="height:100%">
        <div id="silverlightControlHost">
            <object data="data:application/x-silverlight-2," 
            type="application/x-silverlight-2" width="100%" height="100%">
    	<param name="source" value="ClientBin/SilverlightApplicationStart.xap"/>
    	<param name="onError" value="onSilverlightError" />
    	<param name="background" value="white" />
    	<param name="minRuntimeVersion" value="3.0.40624.0" />
    	<param name="autoUpgrade" value="true" />
    	<a href="http://go.microsoft.com/fwlink/?LinkID=149156v=3.0.40624.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>
        </form>
    </body>
    </html>

    В теле страницы содержится объект, код которого находится в файле, указанном в элементе:

    <param name="source" value="ClientBin/SilverlightApplicationStart.xap"/>

    В данном случае - это SilverlightApplicationStart.xap. Для просмотра ресурса достаточно указать в веб-браузере адрес:

    http://localhost/SilverlightApplicationStart.Web/SilverlightApplicationStartTestPage.html

    Возможно также использование SilverlightApplicationStartTestPage.aspx файла вместо SilverlightApplicationStartTestPage.html. Однако для этого потребуется предварительная регистрация нового веб-сайта как приложения (через панель управления IIS).

    3)Добавление анимации. Если между элементами <Grid> </Grid> добавить код, содержащий описание анимации ( Storyboard ) с помощью последовательности трансформаций вращения ( RotateTransform ):

    <Grid.RenderTransform>
    
        <TransformGroup>
          <RotateTransform x:Name="WelcomeRotateTransform"
                           Angle="0" />
        </TransformGroup>
      </Grid.RenderTransform>
    
      <Grid.Triggers>
        <EventTrigger RoutedEvent="Grid.Loaded">
    
          <BeginStoryboard>
            <Storyboard RepeatBehavior="Forever" AutoReverse="True">
    
              <DoubleAnimation Storyboard.TargetName="WelcomeRotateTransform"
                               Storyboard.TargetProperty="Angle"
                               From="0"
                               To="360"
                               Duration="0:0:2" />
    
            </Storyboard>
          </BeginStoryboard>
    
        </EventTrigger>
    
      </Grid.Triggers>

    то получится интересный эффект циклического вращения предыдущей сцены вокруг левого верхнего угла на 360 градусов вперед-назад.

    (рис 23.6 ) Пример Silverlight приложения, использующего анимацию

    Задание 2. Разработка Silverlight -медиаплейера Microsoft Visual Web Developer 2008 Express.

    1) Простое воспроизведение видео с помощью элемента управления MediaElement.

    Создайте новый Silverlight Application проект с именем SLMediaPlayer.

    Добавьте описание элемента MediaElement на страницу MainPage.xaml, указав в качестве значения URL его атрибута Source видеофайл, который хотите воспроизвести. Сам видеофайл можно скопировать в \SLMediaPlayer.Web\ClientBin, например, из стандартной коллекции в директории C:\Users\Public\Videos\Sample Videos\.

    Рассмотрим пример XAML -кода:

    <UserControl x:Class="SLMediaPlayer.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" Background="White"> 
    <MediaElement Source="Wildlife.wmv" /> 
    </Grid> 
    
    </UserControl>

    Данный код обеспечит автоматическую загрузку и воспроизведение видеоролика.

    Размер области воспроизведения мультимедиа определяется следующими правилами:

  • Если заданы свойства Height и Width элемента управления MediaElement, MediaElement использует их.
  • Если задано одно из этих свойств, элемент управления MediaElement растягивает изображение, сохраняя пропорции.
  • Если не заданы ни Height, ни Width, элемент управления MediaElement растягивает изображение до размеров родительского контейнера, сохраняя пропорции.
  • Если заданы оба свойства и они превышают размер области просмотра элемента управления Silverlight, MediaElement обрезает видео соответственно размеру области просмотра.
  • После компиляции и запуска можно будет просмотреть видеоролик в браузере:

    (рис 23.7) Пример простейшего Silverlight приложения, воспроизводящего видеоролик

    2) Расположение содержимого поверх видеоизображения.

    В Silverlight можно размещать текст и графические элементы поверх видеоизображения. Ниже представлен пример XAML код для MediaElement, который перекрывается Canvas с прямоугольником и текстовым блоком:

    <UserControl x:Class="SLMediaPlayer.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" Background="White">
    
            <Canvas Margin="50,50,0,0">
                <MediaElement Source="Wildlife.wmv" Height="200" Width="200" Stretch="Fill" />
                <Rectangle Fill="Black" Height="40" Width="160" />
                <TextBlock Foreground="White">Просмотр видео</TextBlock>
            </Canvas>         
        </Grid>
    
    </UserControl>

    Результат приведен на рисунке ниже.

    (рис 23.8) Пример пример наложения графики на видеоролик в окне браузера

    3) Управление воспроизведением звука.

    Ниже приводится XAML описание элемента MediaElement, определяющее, что звук не выключен, общая громкость составляет 50% и что баланс звука смещен вправо:

    <MediaElement Source="Wildlife.wmv" Height="200" Width="200" 
    Stretch="Fill" IsMuted="False" Volume="0.5" Balance="0.8"/>

    4)Программирование MediaElement

    MediaElement позволяет управлять воспроизведением методами Play, Stop (Остановить) и Pause (Приостановить). Кроме того, имеется возможность взаимодействовать с видео, отслеживая процесс буферизации и загрузки, а также реагировать на маркеры, размещенные в видеофайле. Можно также обрабатывать события, например нажатие кнопок мыши.

    Основными методами управления видео являются Play, Stop и Pause. Если свойству AutoPlay элемента управления MediaElement задано значение false, для начала воспроизведения видео необходимо применить Play. Даже если AutoPlay задано значение true, и воспроизведение начинается автоматически, с помощью этих методов его можно остановить или приостановить.

    Следующий код XAML, в котором имеется элемент мультимедиа и три простых элемента управления воспроизведением, реализованных как элементы TextBlock:

    <UserControl x:Class="SLMediaPlayer.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" Background="White">
    
          <MediaElement x:Name="vid" Source="Wildlife.wmv" />
          <Canvas Canvas.Top="160">
            <Rectangle Fill="Black" Width="200" Height="24" Opacity="0.7"/>
            <TextBlock MouseLeftButtonDown="doPlay" Foreground="White" 
            Canvas.Left="20">Play</TextBlock>
            <TextBlock MouseLeftButtonDown="doStop" Foreground="White" 
            Canvas.Left="80">Stop</TextBlock>
            <TextBlock MouseLeftButtonDown="doPause" Foreground="White" 
            Canvas.Left="140">Pause</TextBlock>
          </Canvas>
    
        </Grid>
    
    </UserControl>

    Для создания элементов управления потребуется задать имя функции, которая должна выполняться в ответ на событие, связанные с мышью, используя атрибут самого элемента управления видео. Это можно реализовать путем обработки события MouseLeftButtonDown для текстового блока, связав их с функциями, воспроизводящими, приостанавливающими или останавливающими воспроизведение.

    Код обработчика событий, связанных с элементами TextBlock необходимо разместить в файле MainPage.xaml.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    namespace SLMediaPlayer
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
            }
    
            private void doPlay(object sender, MouseButtonEventArgs e)
            {
                vid.Play();
            }
    
            private void doPause(object sender, MouseButtonEventArgs e)
            {
                vid.Pause();
            }
    
            private void doStop(object sender, MouseButtonEventArgs e)
            {
                vid.Stop();
            }
    
        }
    }

    Вид приложения в браузер предсавлен на рисунке.

    (рис 23.9) Добавление графических элементов с обработкой событий, связанных с мышью

    5)Управление положением курсора воспроизведения.

    Для управления текущим положением курсора воспроизведения используются свойства NaturalDuration (Номинальная продолжительность) и Position (Положение) элемента мультимедиа. После того, как свойство CurrentState элемента мультимедиа устанавливается в значение Opened, становится возможным получение значения и свойства NaturalDuration. Продолжительность видео в секундах можно получить с помощью NaturalDuration.Seconds и потом преобразовать это значение в часы, минуты и секунды.

    В следующем примере событие CurrentStateChanged элемента управления MediaElement ассоциировано с функцией doState, которая перехватывает значение свойства NaturalDuration.

    Изменим XAML описание медиаплейера:

    <Canvas x:Name="sample9" Opacity="1">
                <MediaElement x:Name="vid" Source="Wildlife.wmv" CurrentStateChanged="doState"/>
                <TextBlock MouseLeftButtonDown="doPlay" Foreground="White" 
                Canvas.Left="20">Play</TextBlock>
                <TextBlock MouseLeftButtonDown="doStop" Foreground="White" 
                Canvas.Left="80">Stop</TextBlock>
                <TextBlock MouseLeftButtonDown="doPause" Foreground="White" 
                    Canvas.Left="140">Pause</TextBlock>
                <TextBlock x:Name="txtStat" Canvas.Left="200" Canvas.Top="0"></TextBlock>
                <TextBlock x:Name="txtBuff" Canvas.Left="200" Canvas.Top="30"></TextBlock>
          </Canvas>

    и соответствующий ему C# код:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    namespace SLMediaPlayer
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
            }
    
            private void doPlay(object sender, MouseButtonEventArgs e)
            {
                vid.Play();
            }
    
            private void doPause(object sender, MouseButtonEventArgs e)
            {
                vid.Pause();
                txtStat.Text = vid.Position.ToString();
            }
    
            private void doStop(object sender, MouseButtonEventArgs e)
            {
                vid.Stop();
            }
    
            private void doState(object sender, RoutedEventArgs e) 
            {
      
                txtBuff.Text = vid.NaturalDuration.ToString();
    
            }
    
        }
    }

    Скриншот работающего приложения, отображающего фактически значения свойств NaturalDuration и Position, можно увидеть на рисунке.

    (рис 23.10) Отображение значений свойст NaturalDuration и Position при воспроизведении видеоролика

    Задание 3. Реализация Deep Zoom в Microsoft Visual Web Developer 2008 Express.

    1)Базовое приложение, которое позволит уменьшать и увеличивать масштаб изображений реализуется с помощью элемента управления ).

    Deep Zoom Composer выполняет простую последовательность операций, включающую Import (Импорт), за которым следует Compose (Компоновка) с последующим Export (Экспорт).

    Работа в Deep Zoom Composer начинается с вкладки Import, где с помощью кнопки Add Image добавляются последовательно все необходимые и заранее подготовленные в графическом редакторе изображения, чтобы выбрать изображение. На рисунке можно увидеть, что добавлены три изображения.

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

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

    (рис 23.12) Окно композиции изображений в Deep Zoom Composer

    На третьем этапе выполняется экспорт. Для этого будем используется вложенная вкладка Custom вкладки Export редактора Deep Zoom Composer

    (рис 23.13) Окно экспорта сцен в Deep Zoom Composer

    На вкладке Export имеется несколько опций. Для экспорта в готовое Silverlight -приложение следует выбрать вкладку Custom, а затем выбрать кнопку-переключатель Silverlight Deep Zoom.

    Чтобы экспортировать метаданные изображений, скомпонованных в Deep Zoom, необходимо присвоить имя проекту и экспортировать проект в заданный каталог. При этом в указанном каталоге появится папка GeneratedImages. Один из файлов в данной папке - SparseImageSceneGraph.xml - является конфигурационным и определяет каждое изображение с указанием его местоположения на других изображениях с разными уровнями увеличения.

    По-сути, редактор Deep Zoom Composer разделяет изображение на равные фрагменты, поэтому при масштабировании рисунка загружается не все изображение, а лишь просматриваемые фрагменты, что очень эффективно при работе с большими изображениями. При просмотре изображения в маленьком масштабе, все фрагменты видны уменьшенными, следовательно, с меньшим разрешением. При увеличении масштаба изображения до пределов разрешающей способности (или выше), видна лишь часть рисунка, т.е. потребуется загружать только те фрагменты, которые представляют видимую часть изображения, что обеспечивает экономию трафика и сокращение времени загрузки.

    Deep Zoom Composer после экспорта в Silverlight Deep Zoom автоматически дополнительно предлагает просмотреть работу Silverlight приложения в браузере.

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

    2)Создайте проект Silverlight приложения в Microsoft Visual Web Developer 2008 Express. В папку ClientBin проекта веб-приложения ASP.NET скопируйте созданную при экспорте папку GeneratedImages.

    Формирование представления содержимого Deep Zoom осуществляется с помощью элемента управления MultiScaleImage. Добавьте MultiScaleImage в файл MainPage.xaml, и в качестве значения его свойства Source задайте местоположение XML -файла с метаданными скомпонованного изображения.

    <UserControl x:Class="DeepZoom.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">
    
        <Canvas>
            <MultiScaleImage x:Name="dz" Source="/GeneratedImages/dzc_output.xml"  H
            eight="480" Width = "640" />
        </Canvas>
    
    </UserControl>

    После компиляции и выполнения полученного Silverlight приложения элемент управления MultiScaleImage cформирует визуальное представление верхнего элемента скомпонованного изображения.

    3)Для перемещения изображения будут использоваться стандартные события, связанные с мышью: MouseLeftButtonDown, MouseLeftButtonUp и MouseMove. Для этого необходимо добавить обработку этих событий элементом MultiScaleImage.

    С этой целью, необходимо внести необходимые изменения в файлы MainPage.xaml и MainPage.xaml.cs:

    <UserControl x:Class="DeepZoom.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">
    
        <Canvas>
    
            <MultiScaleImage x:Name="dz" Source="/GeneratedImages/dzc_output.xml" 
                  MouseLeftButtonDown = "MultiScaleImage_MouseLeftButtonDown" 
                  MouseLeftButtonUp="MultiScaleImage_MouseLeftButtonUp" 
                  MouseMove="MultiScaleImage_MouseMove" 
    Height="480" Width = "640">
            </MultiScaleImage>
    
        </Canvas>
    
    </UserControl>
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    using System.Windows.Browser;
    
    namespace DeepZoom
    {
        public partial class MainPage : UserControl
        {
     
            bool dragging = false; 
            double dx = 0; 
            double dy = 0; 
            Point p0; 
            Point p1; 
            Point pLast;
    
            void Page_Loaded(object sender, RoutedEventArgs e)
            {
                HtmlPage.RegisterScriptableObject("MySilverlightObject", this);
            }
    
            public MainPage()
            {
                InitializeComponent();
            }
    
            private void MultiScaleImage_MouseLeftButtonDown( object sender, MouseButtonEventArgs e) 
            {
             dragging = true;
             p0 = dz.ElementToLogicalPoint(new Point(0, 0));
             p1 = dz.ElementToLogicalPoint(new Point(640, 480));
             dx = 0;
             dy = 0;
             double x = e.GetPosition(null).X;
             double y = e.GetPosition(null).Y;
             pLast = dz.ElementToLogicalPoint(new Point(x, y));
            }
    
            private void MultiScaleImage_MouseLeftButtonUp( object sender, MouseButtonEventArgs e) 
            {
                dragging = false;
                p0 = new Point();
                p1 = new Point();
                pLast = new Point();
                dx = 0;
                dy = 0; 
            }
    
    
            private void MultiScaleImage_MouseMove(object sender, MouseEventArgs e) 
            { 
                if (dragging) 
                { 
                    if (e!=null) 
                      { 
                        double x = e.GetPosition(null).X; 
                        double y = e.GetPosition(null).Y;
                        Point pCurrent = dz.ElementToLogicalPoint(new Point(x, y)); 
                        if (pLast != null) 
                          { 
                              dx += (pCurrent.X - pLast.X); 
                              dy += (pCurrent.Y - pLast.Y); 
                              Point origin = new Point(p0.X - dx, p0.Y - dy); 
                              dz.ViewportOrigin = origin; 
                          } 
                        pLast = pCurrent; 
                    } 
                } 
    
            }
    
        }
    }

    Предполагается, что пользователь удерживает кнопку мыши и двигает мышью, поэтому свойству dragging (перетягивание) присваивается значение true. Далее, необходимо получить текущие координаты видимой части изображения. В Silverlight логические координаты верхнего левого угла и нижнего правого угла окна можно получить с помощью метода ElementToLogicalPoint, передав в него физические координаты. Кроме того, необходимо получать логические координаты курсора мыши. Для этого вызывается API ElementToLogicalPoint, в него передается текущее положение мыши (которое можно получить из объекта MouseEventArgs, передаваемого в эту функцию) и возвращаемые результаты сохраняются в переменной pLast.

    4)Создание функциональности масштабирования с использованием колеса мыши.

    Для потребуется добавить в элемент MultiScaleImage обработку события MouseWheel:

    <MultiScaleImage x:Name="dz" Source="/GeneratedImages/dzc_output.xml" 
                  MouseLeftButtonDown = "MultiScaleImage_MouseLeftButtonDown"  
                  MouseLeftButtonUp="MultiScaleImage_MouseLeftButtonUp" 
                  MouseMove="MultiScaleImage_MouseMove"  MouseWheel="MultiScaleImage_MouseWheel"  
                 Height="480" Width = "640">
    </MultiScaleImage>

    и в файле MainPage.xaml.cs описание метода MultiScaleImage_MouseWheel класса UserControl:

    private void MultiScaleImage_MouseWheel(object sender,  MouseWheelEventArgs e)
    {   
                double dZoomFactor = 1.33;
                if (e.Delta < 0) dZoomFactor = 1 / 1.33;
                Point pz = dz.ElementToLogicalPoint(new Point(e.GetPosition(
                null).X, e.GetPosition(null).Y));
                dz.ZoomAboutLogicalPoint(dZoomFactor, pz.X, pz.Y);
    }

    Скриншоты работы в веб-браузере Silverlight приложения с поддержкой перемещения и масштабирования для композиции из изображений с разными уровнями детализации приведены ниже.

    (рис 23.14) Просмотр в веб-браузере Deep Zoom сцены с последовательным увеличением уровня детализации

    Задание 4. Работа с коллекциям Deep Zoom в Silverlight.

    Кроме возможности увеличения и уменьшения изображения, можно также создавать коллекции изображений и работать с ними в масштабируемой среде.

    При экспорте изображений из редактора Deep Zoom предлагается опция " Create Collection " (cоздать коллекцию), которая обеспечивает создание коллекции изображений.

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

    5) С помощью Deep Zoom Compose подготовьте коллекцию изображений и экспортируйте с опцией " Create Collection ".

    6) Создайте проект Silverlight приложения в Microsoft Visual Web Developer 2008 Express. В папку ClientBin проекта веб-приложения ASP.NET скопируйте созданную при экспорте папку GeneratedImages.

    Формирование представления содержимого Deep Zoom осуществляется с помощью элемента управления MultiScaleImage. Добавьте MultiScaleImage в файл MainPage.xaml, и в качестве значения его свойства Source задайте местоположение XML -файла с метаданными скомпонованного изображения.

    Содержимое файлов MainPage.xaml и MainPage.xaml.cs приводится ниже.

    <UserControl x:Class="DeepZoomCollection.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">
        <Canvas>
            <MultiScaleImage x:Name="dz" Source="/GeneratedImages/dzc_output.xml" 
                      ImageOpenSucceeded="dz_ImageOpenSucceeded" Height="480" Width="640">
            </MultiScaleImage> 
        </Canvas>
    </UserControl>
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    namespace DeepZoomCollection
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
            }
    
            private void dz_ImageOpenSucceeded(object sender, RoutedEventArgs e)
            {
                int nImages = dz.SubImages.Count; 
                for (int lp = 0; lp < nImages; lp++)
                {
                    dz.SubImages[lp].ViewportOrigin = new Point(-lp * 0.5, -lp * 0.5);
                }
            }
        }
    }

    В случае с коллекцией, работа с каждым изображением осуществляется через SubImages[lp] , где lp - переменная цикла, которая может принимать значения от 0 до числа, соответствующего количеству изображений в коллекции.

    (рис 23.15) Просмотр Deep Zoom коллекции

    Самостоятельное задание

    Создайте графический индикатор времени просмотра видеоролика в виде прямоугольника, длина которого динамически пересчитывается (с обновлением вида фигуры) при нажатии "Pause" по формуле:

    $$ширина\ видеокадра * Position / NaturalDuration$$
    Страницы:

    Задание 1. Создание простого Silverlight -приложения в Microsoft Visual Web Developer 2008 Express.

    1) С помощью раздела меню File -> New Project (или комбинации <Ctrl>+<Shift>+<N> ) необходимо открыть окно для выбора шаблона проекта.

    (рис 23.1) Создание нового Silverlight проекта

    В списке проектов для Silverlight будут доступны шаблоны Silverlight Application (приложение Silverlight ), Silverlight Navigation Application (приложение Silverlight с поддержкой навигации) и Silverlight Class Library (библиотека классов Silverlight ). Необходимо выбрать шаблон Silverlight Application, задать имя и местоположение нового проекта. После нажатия OK будет запущен New Silverlight Application Wizard (Мастер нового приложения Silverlight ).

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

    (рис 23.2) Выбор типа Silverlight приложения

    Необходимо выбрать вариант ASP.NET Web Site и создать проект.

    (рис 23.3) Вид нового Silverlight проекта в VWDE

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

    (рис 23.4) Структура нового Silverlight проекта

    Как видно из рисунка, проект содержит два решения: базовый элемент управления Silverlight (SilverlighApplicationStart) и веб-приложение (SilverlighApplicationStart.Web) . Созданный шаблоном базовый проект содержит ряд файлов, включая манифест приложения AppManifest.xml, XAML -файл приложения App.xaml с файлом выделенного кода App.xaml.cs, страницу-пример Default.aspx с файлом выделенного кода Default.aspx.cs, информационный файл сборки AssemblyInfo.cs и некоторые ссылки.

    AppManifest.xml создается при компиляции проекта. Если проект имеет какие-либо зависимости во время выполнения, например, внешние элементы управления, то ссылки на них размещаются в этом файле.

    Файл Assemblyinfo.cs содержит метаданные, которые должны быть скомпилированы в DLL.

    Папка References содержит ссылки на ряд сборок. Это основные сборки Silverlight, которые необходимы для запуска приложения.

  • Mscorlib - В сборку входят основные типы, используемые приложениями Silverlight.
  • System - В сборку входят многие высокоуровневые типы, используемые для разработки и отладки приложений Silverlight, такие как компилятор и классы для отладки и диагностики.
  • System.Core - Сборка включает основные элементы управления и классы Silverlight.
  • System.Net - Сборка включает библиотеки .NET, необходимые для сетевого взаимодействия.
  • System.Xml - В сборку входят библиотеки Silverlight для обработки XML.
  • System.Windows - В сборку входят основные функциональные возможности Windows и Silverlight, включая элементы управления Silverlight.
  • System.Windows.Browser - В сборку входят библиотеки, используемые для взаимодействия с браузером.
  • Файл App.xaml создается интегрированной средой разработки при создании проекта Silverlight по шаблону. Обычно он используется для хранения общей информации всего приложения. App.xaml содержит объявления, определяющие поведение приложения.

    <Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
                 x:Class="SilverlightApplicationStart.App"
                 >
        <Application.Resources>
            
        </Application.Resources>
    </Application>

    Атрибут x:Class определяет имя класса, в который будет скомпилирован этот XAML файл и связанный с ним файл выделенного кода App.xaml.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    namespace SilverlightApplicationStart
    {
        public partial class App : Application
        {
    
            public App()
            {
                this.Startup += this.Application_Startup;
                this.Exit += this.Application_Exit;
                this.UnhandledException += this.Application_UnhandledException;
    
                InitializeComponent();
            }
    
            private void Application_Startup(object sender, StartupEventArgs e)
            {
                this.RootVisual = new MainPage();
            }
    
            private void Application_Exit(object sender, EventArgs e)
            {
    
            }
            private void Application_UnhandledException(object sender, 
            ApplicationUnhandledExceptionEventArgs e)
            {
                // If the app is running outside of the debugger then report the exception using
                // the browser's exception mechanism. On IE this will display it a yellow alert 
                // icon in the status bar and Firefox will display a script error.
                if (!System.Diagnostics.Debugger.IsAttached)
                {
    
                    // NOTE: This will allow the application to continue running 
                    after an exception has been thrown
                    // but not handled. 
                    // For production applications this error handling should 
                    be replaced with something that will 
                    // report the error to the website and stop the application.
                    e.Handled = true;
                    Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
                }
            }
            private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e)
            {
                try
                {
                    string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace;
                    errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n");
    
                    System.Windows.Browser.HtmlPage.Window.Eval("throw new Error
                    (\"Unhandled Error in Silverlight Application " + errorMsg + "\");");
                }
                catch (Exception)
                {
                }
            }
        }
    }

    Конструктор App() используется для подключения методов Application_Startup и Application_Exit.

    Методы Application_Startup и Application_Exit принимают два параметра: объект, формирующий событие, и объект аргументов.

    В методе Application_Startup происходит присвоение свойству RootVisual (Корневой визуальный элемент) приложения нового объекта MainPage (Главная страница). Тем самым объявляется, что UI ( user interface - пользовательский интерфейс) объекта Page является первым экраном UI, который должно создать это приложение. Все другие экраны UI, объявленные в XAML, должны будут запускаться из объекта MainPage. Объект MainPage является XAML -объектом по умолчанию, создаваемым шаблоном для размещения UI приложения.

    Файл MainPage.xaml является для приложения UI по умолчанию. При компиляции вместе с ассоциированным с ним файлом выделенного кода он формирует класс MainPage, экземпляр которого будет объектом MainPage:

    <UserControl x:Class="SilverlightApplicationStart.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>
    </UserControl>

    Контейнером XAML является UserControl. При построении .NET -приложений Silverlight в Visual Studio, фактически, создаются элементы управления, которые компилируются в DLL -файл и помещаются в XAP -файл, который затем открывает и исполняет Silverlight.

    Экземпляр UserControl называется SilverlightApplicationStart.MainPage, где SilverlightApplicationStart - это пространство имен, а MainPage - имя класса из этого пространства имен.

    Объявления xmlns и xmlns:x задают пространство имен по умолчанию и дополнительное пространство имен, которые должны использоваться для проверки корректности XAML.

    Для ширины и высоты заданы значения по умолчанию: 640 ? 480.

    Далее следует корневой элемент Grid. В Silverlight 3 корневым элементом должен быть элемент Container, которым в данном случае является Grid с именем LayoutRoot. Следовательно, все элементы дизайна UI являются дочерними элементами данного узла.

    Рассмотрим выделенный код MainPage.xaml.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    namespace SilverlightApplicationStart
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
            }
        }
    }

    Это описание стандартного класса MainPage, унаследованного от UserControl. В конструкторе класса выполняется общая настройка с помощью вызова метода InitializeComponent().

    В дальнейших примерах именно в этот модуль будет добавляться специфический для веб-приложений код.

    Шаблон помимо проекта элемента управления, создает также веб-проект, в котором размещается Silverlight -приложение. Веб-проект включает два ASPX -файла: Default.aspx, содержащий пустую веб-форму, на базе которой можно построить свое приложение; и тестовую страницу SilverlightApplicationStartTestPage.aspx, которая содержит все необходимое для запуска Silverlight из ASP.NET.

    Хотя Silverlight не имеет никаких зависимостей на стороне сервера, ASP.NET предлагает элементы управления, обеспечивающие возможность создания JavaScript и HTML на стороне клиента, необходимых для размещения Silverlight в браузере.

    2) Создание простейшей сцены.

    Вставьте в файл MainPage.xaml следующий код на языке XAML:

    <UserControl x:Class="SilverlightApplicationStart.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="800" d:DesignHeight="600" >
       
        <Grid x:Name="LayoutRoot" Width="400"
            Height="300"
            Canvas.Left="120"
            Canvas.Top="110"
            Background="Red">
    
            <Rectangle Width="240" 
                 Height="150"
                 Fill="Yellow"
                 Margin="40" 
    Canvas.ZIndex="0"/>
    
            <Ellipse Width="200"
                 Height="140"
                 Fill="#CCFFFFFF"
                 HorizontalAlignment="Right"
                 VerticalAlignment="Bottom"
                 Margin="60" />
            
            <TextBlock Text="Hello world"
                   FontSize="28"
                   Foreground="Blue"
                   Margin="110" >
            </TextBlock>
    
        </Grid>
    </UserControl>

    Сцена содержит 4 объекта: контейнер ( Grid ) красного цвета, желтый прямоугольник ( Rectangle ), белый эллипс ( Ellipse ) с атрибутом прозрачности и текстовый блок ( TextBlock ) голубого цвета.

    После компиляции ( <Ctrl>+<Shift>+<B> ) и запуска ( <Ctrl>+<F5> ) проекта в веб-браузере будет автоматически загружен документ:

    http://localhost:port/SilverlightApplicationStart.Web/SilverlightApplicationStartTestPage.aspx

    следующего вида:

    (рис 23.5) Пример простейшего Silverlight приложения

    Можно теперь разместить полученный контент Silverlight на веб-сервер. Для этого необходимо скопировать целиком папку SilverlightApplicationStart.Web на веб-сервер. В указанном каталоге содержится файл SilverlightApplicationStartTestPage.html, содержащий ссылку на Silverlight ресурс:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" >
    
    <head>
        <title>SilverlightApplicationStart</title>
        <style type="text/css">
        html, body {
    	    height: 100%;
    	    overflow: auto;
        }
        body {
    	    padding: 0;
    	    margin: 0;
        }
        #silverlightControlHost {
    	    height: 100%;
    	    text-align:center;
        }
        </style>
    
        <script type="text/javascript" src="Silverlight.js"></script>
        <script type="text/javascript">
            function onSilverlightError(sender, args) {
                var appSource = "";
                if (sender != null  sender != 0) {
                  appSource = sender.getHost().Source;
                }
                
                var errorType = args.ErrorType;
                var iErrorCode = args.ErrorCode;
    
                if (errorType == "ImageError" || errorType == "MediaError") {
                  return;
                }
    
                var errMsg = "Unhandled Error in Silverlight Application " +  appSource + "\n" ;
    
                errMsg += "Code: "+ iErrorCode + "    \n";
                errMsg += "Category: " + errorType + "       \n";
                errMsg += "Message: " + args.ErrorMessage + "     \n";
    
                if (errorType == "ParserError") {
                    errMsg += "File: " + args.xamlFile + "     \n";
                    errMsg += "Line: " + args.lineNumber + "     \n";
                    errMsg += "Position: " + args.charPosition + "     \n";
                }
                else if (errorType == "RuntimeError") {           
                    if (args.lineNumber != 0) {
                        errMsg += "Line: " + args.lineNumber + "     \n";
                        errMsg += "Position: " +  args.charPosition + "     \n";
                    }
                    errMsg += "MethodName: " + args.methodName + "     \n";
                }
    
                throw new Error(errMsg);
            }
        </script>
    </head>
    
    <body>
        <form id="form1" runat="server" style="height:100%">
        <div id="silverlightControlHost">
            <object data="data:application/x-silverlight-2," 
            type="application/x-silverlight-2" width="100%" height="100%">
    	<param name="source" value="ClientBin/SilverlightApplicationStart.xap"/>
    	<param name="onError" value="onSilverlightError" />
    	<param name="background" value="white" />
    	<param name="minRuntimeVersion" value="3.0.40624.0" />
    	<param name="autoUpgrade" value="true" />
    	<a href="http://go.microsoft.com/fwlink/?LinkID=149156v=3.0.40624.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>
        </form>
    </body>
    </html>

    В теле страницы содержится объект, код которого находится в файле, указанном в элементе:

    <param name="source" value="ClientBin/SilverlightApplicationStart.xap"/>

    В данном случае - это SilverlightApplicationStart.xap. Для просмотра ресурса достаточно указать в веб-браузере адрес:

    http://localhost/SilverlightApplicationStart.Web/SilverlightApplicationStartTestPage.html

    Возможно также использование SilverlightApplicationStartTestPage.aspx файла вместо SilverlightApplicationStartTestPage.html. Однако для этого потребуется предварительная регистрация нового веб-сайта как приложения (через панель управления IIS).

    3)Добавление анимации. Если между элементами <Grid> </Grid> добавить код, содержащий описание анимации ( Storyboard ) с помощью последовательности трансформаций вращения ( RotateTransform ):

    <Grid.RenderTransform>
    
        <TransformGroup>
          <RotateTransform x:Name="WelcomeRotateTransform"
                           Angle="0" />
        </TransformGroup>
      </Grid.RenderTransform>
    
      <Grid.Triggers>
        <EventTrigger RoutedEvent="Grid.Loaded">
    
          <BeginStoryboard>
            <Storyboard RepeatBehavior="Forever" AutoReverse="True">
    
              <DoubleAnimation Storyboard.TargetName="WelcomeRotateTransform"
                               Storyboard.TargetProperty="Angle"
                               From="0"
                               To="360"
                               Duration="0:0:2" />
    
            </Storyboard>
          </BeginStoryboard>
    
        </EventTrigger>
    
      </Grid.Triggers>

    то получится интересный эффект циклического вращения предыдущей сцены вокруг левого верхнего угла на 360 градусов вперед-назад.

    (рис 23.6 ) Пример Silverlight приложения, использующего анимацию

    Задание 2. Разработка Silverlight -медиаплейера Microsoft Visual Web Developer 2008 Express.

    1) Простое воспроизведение видео с помощью элемента управления MediaElement.

    Создайте новый Silverlight Application проект с именем SLMediaPlayer.

    Добавьте описание элемента MediaElement на страницу MainPage.xaml, указав в качестве значения URL его атрибута Source видеофайл, который хотите воспроизвести. Сам видеофайл можно скопировать в \SLMediaPlayer.Web\ClientBin, например, из стандартной коллекции в директории C:\Users\Public\Videos\Sample Videos\.

    Рассмотрим пример XAML -кода:

    <UserControl x:Class="SLMediaPlayer.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" Background="White"> 
    <MediaElement Source="Wildlife.wmv" /> 
    </Grid> 
    
    </UserControl>

    Данный код обеспечит автоматическую загрузку и воспроизведение видеоролика.

    Размер области воспроизведения мультимедиа определяется следующими правилами:

  • Если заданы свойства Height и Width элемента управления MediaElement, MediaElement использует их.
  • Если задано одно из этих свойств, элемент управления MediaElement растягивает изображение, сохраняя пропорции.
  • Если не заданы ни Height, ни Width, элемент управления MediaElement растягивает изображение до размеров родительского контейнера, сохраняя пропорции.
  • Если заданы оба свойства и они превышают размер области просмотра элемента управления Silverlight, MediaElement обрезает видео соответственно размеру области просмотра.
  • После компиляции и запуска можно будет просмотреть видеоролик в браузере:

    (рис 23.7) Пример простейшего Silverlight приложения, воспроизводящего видеоролик

    2) Расположение содержимого поверх видеоизображения.

    В Silverlight можно размещать текст и графические элементы поверх видеоизображения. Ниже представлен пример XAML код для MediaElement, который перекрывается Canvas с прямоугольником и текстовым блоком:

    <UserControl x:Class="SLMediaPlayer.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" Background="White">
    
            <Canvas Margin="50,50,0,0">
                <MediaElement Source="Wildlife.wmv" Height="200" Width="200" Stretch="Fill" />
                <Rectangle Fill="Black" Height="40" Width="160" />
                <TextBlock Foreground="White">Просмотр видео</TextBlock>
            </Canvas>         
        </Grid>
    
    </UserControl>

    Результат приведен на рисунке ниже.

    (рис 23.8) Пример пример наложения графики на видеоролик в окне браузера

    3) Управление воспроизведением звука.

    Ниже приводится XAML описание элемента MediaElement, определяющее, что звук не выключен, общая громкость составляет 50% и что баланс звука смещен вправо:

    <MediaElement Source="Wildlife.wmv" Height="200" Width="200" 
    Stretch="Fill" IsMuted="False" Volume="0.5" Balance="0.8"/>

    4)Программирование MediaElement

    MediaElement позволяет управлять воспроизведением методами Play, Stop (Остановить) и Pause (Приостановить). Кроме того, имеется возможность взаимодействовать с видео, отслеживая процесс буферизации и загрузки, а также реагировать на маркеры, размещенные в видеофайле. Можно также обрабатывать события, например нажатие кнопок мыши.

    Основными методами управления видео являются Play, Stop и Pause. Если свойству AutoPlay элемента управления MediaElement задано значение false, для начала воспроизведения видео необходимо применить Play. Даже если AutoPlay задано значение true, и воспроизведение начинается автоматически, с помощью этих методов его можно остановить или приостановить.

    Следующий код XAML, в котором имеется элемент мультимедиа и три простых элемента управления воспроизведением, реализованных как элементы TextBlock:

    <UserControl x:Class="SLMediaPlayer.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" Background="White">
    
          <MediaElement x:Name="vid" Source="Wildlife.wmv" />
          <Canvas Canvas.Top="160">
            <Rectangle Fill="Black" Width="200" Height="24" Opacity="0.7"/>
            <TextBlock MouseLeftButtonDown="doPlay" Foreground="White" 
            Canvas.Left="20">Play</TextBlock>
            <TextBlock MouseLeftButtonDown="doStop" Foreground="White" 
            Canvas.Left="80">Stop</TextBlock>
            <TextBlock MouseLeftButtonDown="doPause" Foreground="White" 
            Canvas.Left="140">Pause</TextBlock>
          </Canvas>
    
        </Grid>
    
    </UserControl>

    Для создания элементов управления потребуется задать имя функции, которая должна выполняться в ответ на событие, связанные с мышью, используя атрибут самого элемента управления видео. Это можно реализовать путем обработки события MouseLeftButtonDown для текстового блока, связав их с функциями, воспроизводящими, приостанавливающими или останавливающими воспроизведение.

    Код обработчика событий, связанных с элементами TextBlock необходимо разместить в файле MainPage.xaml.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    namespace SLMediaPlayer
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
            }
    
            private void doPlay(object sender, MouseButtonEventArgs e)
            {
                vid.Play();
            }
    
            private void doPause(object sender, MouseButtonEventArgs e)
            {
                vid.Pause();
            }
    
            private void doStop(object sender, MouseButtonEventArgs e)
            {
                vid.Stop();
            }
    
        }
    }

    Вид приложения в браузер предсавлен на рисунке.

    (рис 23.9) Добавление графических элементов с обработкой событий, связанных с мышью

    5)Управление положением курсора воспроизведения.

    Для управления текущим положением курсора воспроизведения используются свойства NaturalDuration (Номинальная продолжительность) и Position (Положение) элемента мультимедиа. После того, как свойство CurrentState элемента мультимедиа устанавливается в значение Opened, становится возможным получение значения и свойства NaturalDuration. Продолжительность видео в секундах можно получить с помощью NaturalDuration.Seconds и потом преобразовать это значение в часы, минуты и секунды.

    В следующем примере событие CurrentStateChanged элемента управления MediaElement ассоциировано с функцией doState, которая перехватывает значение свойства NaturalDuration.

    Изменим XAML описание медиаплейера:

    <Canvas x:Name="sample9" Opacity="1">
                <MediaElement x:Name="vid" Source="Wildlife.wmv" CurrentStateChanged="doState"/>
                <TextBlock MouseLeftButtonDown="doPlay" Foreground="White" 
                Canvas.Left="20">Play</TextBlock>
                <TextBlock MouseLeftButtonDown="doStop" Foreground="White" 
                Canvas.Left="80">Stop</TextBlock>
                <TextBlock MouseLeftButtonDown="doPause" Foreground="White" 
                    Canvas.Left="140">Pause</TextBlock>
                <TextBlock x:Name="txtStat" Canvas.Left="200" Canvas.Top="0"></TextBlock>
                <TextBlock x:Name="txtBuff" Canvas.Left="200" Canvas.Top="30"></TextBlock>
          </Canvas>

    и соответствующий ему C# код:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    namespace SLMediaPlayer
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
            }
    
            private void doPlay(object sender, MouseButtonEventArgs e)
            {
                vid.Play();
            }
    
            private void doPause(object sender, MouseButtonEventArgs e)
            {
                vid.Pause();
                txtStat.Text = vid.Position.ToString();
            }
    
            private void doStop(object sender, MouseButtonEventArgs e)
            {
                vid.Stop();
            }
    
            private void doState(object sender, RoutedEventArgs e) 
            {
      
                txtBuff.Text = vid.NaturalDuration.ToString();
    
            }
    
        }
    }

    Скриншот работающего приложения, отображающего фактически значения свойств NaturalDuration и Position, можно увидеть на рисунке.

    (рис 23.10) Отображение значений свойст NaturalDuration и Position при воспроизведении видеоролика

    Задание 3. Реализация Deep Zoom в Microsoft Visual Web Developer 2008 Express.

    1)Базовое приложение, которое позволит уменьшать и увеличивать масштаб изображений реализуется с помощью элемента управления ).

    Deep Zoom Composer выполняет простую последовательность операций, включающую Import (Импорт), за которым следует Compose (Компоновка) с последующим Export (Экспорт).

    Работа в Deep Zoom Composer начинается с вкладки Import, где с помощью кнопки Add Image добавляются последовательно все необходимые и заранее подготовленные в графическом редакторе изображения, чтобы выбрать изображение. На рисунке можно увидеть, что добавлены три изображения.

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

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

    (рис 23.12) Окно композиции изображений в Deep Zoom Composer

    На третьем этапе выполняется экспорт. Для этого будем используется вложенная вкладка Custom вкладки Export редактора Deep Zoom Composer

    (рис 23.13) Окно экспорта сцен в Deep Zoom Composer

    На вкладке Export имеется несколько опций. Для экспорта в готовое Silverlight -приложение следует выбрать вкладку Custom, а затем выбрать кнопку-переключатель Silverlight Deep Zoom.

    Чтобы экспортировать метаданные изображений, скомпонованных в Deep Zoom, необходимо присвоить имя проекту и экспортировать проект в заданный каталог. При этом в указанном каталоге появится папка GeneratedImages. Один из файлов в данной папке - SparseImageSceneGraph.xml - является конфигурационным и определяет каждое изображение с указанием его местоположения на других изображениях с разными уровнями увеличения.

    По-сути, редактор Deep Zoom Composer разделяет изображение на равные фрагменты, поэтому при масштабировании рисунка загружается не все изображение, а лишь просматриваемые фрагменты, что очень эффективно при работе с большими изображениями. При просмотре изображения в маленьком масштабе, все фрагменты видны уменьшенными, следовательно, с меньшим разрешением. При увеличении масштаба изображения до пределов разрешающей способности (или выше), видна лишь часть рисунка, т.е. потребуется загружать только те фрагменты, которые представляют видимую часть изображения, что обеспечивает экономию трафика и сокращение времени загрузки.

    Deep Zoom Composer после экспорта в Silverlight Deep Zoom автоматически дополнительно предлагает просмотреть работу Silverlight приложения в браузере.

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

    2)Создайте проект Silverlight приложения в Microsoft Visual Web Developer 2008 Express. В папку ClientBin проекта веб-приложения ASP.NET скопируйте созданную при экспорте папку GeneratedImages.

    Формирование представления содержимого Deep Zoom осуществляется с помощью элемента управления MultiScaleImage. Добавьте MultiScaleImage в файл MainPage.xaml, и в качестве значения его свойства Source задайте местоположение XML -файла с метаданными скомпонованного изображения.

    <UserControl x:Class="DeepZoom.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">
    
        <Canvas>
            <MultiScaleImage x:Name="dz" Source="/GeneratedImages/dzc_output.xml"  H
            eight="480" Width = "640" />
        </Canvas>
    
    </UserControl>

    После компиляции и выполнения полученного Silverlight приложения элемент управления MultiScaleImage cформирует визуальное представление верхнего элемента скомпонованного изображения.

    3)Для перемещения изображения будут использоваться стандартные события, связанные с мышью: MouseLeftButtonDown, MouseLeftButtonUp и MouseMove. Для этого необходимо добавить обработку этих событий элементом MultiScaleImage.

    С этой целью, необходимо внести необходимые изменения в файлы MainPage.xaml и MainPage.xaml.cs:

    <UserControl x:Class="DeepZoom.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">
    
        <Canvas>
    
            <MultiScaleImage x:Name="dz" Source="/GeneratedImages/dzc_output.xml" 
                  MouseLeftButtonDown = "MultiScaleImage_MouseLeftButtonDown" 
                  MouseLeftButtonUp="MultiScaleImage_MouseLeftButtonUp" 
                  MouseMove="MultiScaleImage_MouseMove" 
    Height="480" Width = "640">
            </MultiScaleImage>
    
        </Canvas>
    
    </UserControl>
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    using System.Windows.Browser;
    
    namespace DeepZoom
    {
        public partial class MainPage : UserControl
        {
     
            bool dragging = false; 
            double dx = 0; 
            double dy = 0; 
            Point p0; 
            Point p1; 
            Point pLast;
    
            void Page_Loaded(object sender, RoutedEventArgs e)
            {
                HtmlPage.RegisterScriptableObject("MySilverlightObject", this);
            }
    
            public MainPage()
            {
                InitializeComponent();
            }
    
            private void MultiScaleImage_MouseLeftButtonDown( object sender, MouseButtonEventArgs e) 
            {
             dragging = true;
             p0 = dz.ElementToLogicalPoint(new Point(0, 0));
             p1 = dz.ElementToLogicalPoint(new Point(640, 480));
             dx = 0;
             dy = 0;
             double x = e.GetPosition(null).X;
             double y = e.GetPosition(null).Y;
             pLast = dz.ElementToLogicalPoint(new Point(x, y));
            }
    
            private void MultiScaleImage_MouseLeftButtonUp( object sender, MouseButtonEventArgs e) 
            {
                dragging = false;
                p0 = new Point();
                p1 = new Point();
                pLast = new Point();
                dx = 0;
                dy = 0; 
            }
    
    
            private void MultiScaleImage_MouseMove(object sender, MouseEventArgs e) 
            { 
                if (dragging) 
                { 
                    if (e!=null) 
                      { 
                        double x = e.GetPosition(null).X; 
                        double y = e.GetPosition(null).Y;
                        Point pCurrent = dz.ElementToLogicalPoint(new Point(x, y)); 
                        if (pLast != null) 
                          { 
                              dx += (pCurrent.X - pLast.X); 
                              dy += (pCurrent.Y - pLast.Y); 
                              Point origin = new Point(p0.X - dx, p0.Y - dy); 
                              dz.ViewportOrigin = origin; 
                          } 
                        pLast = pCurrent; 
                    } 
                } 
    
            }
    
        }
    }

    Предполагается, что пользователь удерживает кнопку мыши и двигает мышью, поэтому свойству dragging (перетягивание) присваивается значение true. Далее, необходимо получить текущие координаты видимой части изображения. В Silverlight логические координаты верхнего левого угла и нижнего правого угла окна можно получить с помощью метода ElementToLogicalPoint, передав в него физические координаты. Кроме того, необходимо получать логические координаты курсора мыши. Для этого вызывается API ElementToLogicalPoint, в него передается текущее положение мыши (которое можно получить из объекта MouseEventArgs, передаваемого в эту функцию) и возвращаемые результаты сохраняются в переменной pLast.

    4)Создание функциональности масштабирования с использованием колеса мыши.

    Для потребуется добавить в элемент MultiScaleImage обработку события MouseWheel:

    <MultiScaleImage x:Name="dz" Source="/GeneratedImages/dzc_output.xml" 
                  MouseLeftButtonDown = "MultiScaleImage_MouseLeftButtonDown"  
                  MouseLeftButtonUp="MultiScaleImage_MouseLeftButtonUp" 
                  MouseMove="MultiScaleImage_MouseMove"  MouseWheel="MultiScaleImage_MouseWheel"  
                 Height="480" Width = "640">
    </MultiScaleImage>

    и в файле MainPage.xaml.cs описание метода MultiScaleImage_MouseWheel класса UserControl:

    private void MultiScaleImage_MouseWheel(object sender,  MouseWheelEventArgs e)
    {   
                double dZoomFactor = 1.33;
                if (e.Delta < 0) dZoomFactor = 1 / 1.33;
                Point pz = dz.ElementToLogicalPoint(new Point(e.GetPosition(
                null).X, e.GetPosition(null).Y));
                dz.ZoomAboutLogicalPoint(dZoomFactor, pz.X, pz.Y);
    }

    Скриншоты работы в веб-браузере Silverlight приложения с поддержкой перемещения и масштабирования для композиции из изображений с разными уровнями детализации приведены ниже.

    (рис 23.14) Просмотр в веб-браузере Deep Zoom сцены с последовательным увеличением уровня детализации

    Задание 4. Работа с коллекциям Deep Zoom в Silverlight.

    Кроме возможности увеличения и уменьшения изображения, можно также создавать коллекции изображений и работать с ними в масштабируемой среде.

    При экспорте изображений из редактора Deep Zoom предлагается опция " Create Collection " (cоздать коллекцию), которая обеспечивает создание коллекции изображений.

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

    5) С помощью Deep Zoom Compose подготовьте коллекцию изображений и экспортируйте с опцией " Create Collection ".

    6) Создайте проект Silverlight приложения в Microsoft Visual Web Developer 2008 Express. В папку ClientBin проекта веб-приложения ASP.NET скопируйте созданную при экспорте папку GeneratedImages.

    Формирование представления содержимого Deep Zoom осуществляется с помощью элемента управления MultiScaleImage. Добавьте MultiScaleImage в файл MainPage.xaml, и в качестве значения его свойства Source задайте местоположение XML -файла с метаданными скомпонованного изображения.

    Содержимое файлов MainPage.xaml и MainPage.xaml.cs приводится ниже.

    <UserControl x:Class="DeepZoomCollection.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">
        <Canvas>
            <MultiScaleImage x:Name="dz" Source="/GeneratedImages/dzc_output.xml" 
                      ImageOpenSucceeded="dz_ImageOpenSucceeded" Height="480" Width="640">
            </MultiScaleImage> 
        </Canvas>
    </UserControl>
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    namespace DeepZoomCollection
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
            }
    
            private void dz_ImageOpenSucceeded(object sender, RoutedEventArgs e)
            {
                int nImages = dz.SubImages.Count; 
                for (int lp = 0; lp < nImages; lp++)
                {
                    dz.SubImages[lp].ViewportOrigin = new Point(-lp * 0.5, -lp * 0.5);
                }
            }
        }
    }

    В случае с коллекцией, работа с каждым изображением осуществляется через SubImages[lp] , где lp - переменная цикла, которая может принимать значения от 0 до числа, соответствующего количеству изображений в коллекции.

    (рис 23.15) Просмотр Deep Zoom коллекции

    Самостоятельное задание

    Создайте графический индикатор времени просмотра видеоролика в виде прямоугольника, длина которого динамически пересчитывается (с обновлением вида фигуры) при нажатии "Pause" по формуле:

    $$ширина\ видеокадра * Position / NaturalDuration$$
    Вернуться к учебному плану