Опубликован: 01.03.2010 | Доступ: свободный | Студентов: 958 / 46 | Оценка: 4.38 / 4.31 | Длительность: 09:26:00
Лекция 6:

Вставка приложений Silverlight в web приложения

< Лекция 5 || Лекция 6: 1234 || Лекция 7 >

Silverlight и HTML, AJAX и JavaScript

В разделе Вставка приложений Silverlight в web-приложения описан процесс вставки приложения Silverlight на веб-страницу. Но приложение Silverlight может взаимодействовать с кодом JavaScript или AJAX, а так же другими элементами HTML на странице где оно размещено.

Существует несколько направлений или философий для разработки для Веб. Одна нацелена на возможности браузера, где логику обеспечивает JavaScript, динамический HTML, каскадные таблицы стилей и AJAX. Другое направление - логика полностью на сервере, а браузер разработан для отображения документов, а не приложений. В таком подходе философия такова, что создавать приложения, удовлетворяющие все возрастающим требованиям пользователей, полагаясь только на браузер, нецелесообразно.

Silverlight является золотой серединой между этих двух подходов, является мостом. Silverlight включает "доступ к браузеру", которая предоставляет разработчикам и дизайнерам неограниченные возможности для реализации приложений любой сложности. Использование механизма доступа к объектной модели браузера обеспечивает следующие возможности:

  • Любой код, откомпилированный в сборку Microsoft .NET Framework, доступен браузеру и может быть вызван из JavaScript.
  • Любой JavaScript-код в браузере доступен из .NET-сборки и может вызываться из Silverlight-приложения.
  • Дерево визуального представления XAML доступно браузеру. С помощью JavaScript вы можете создавать XAML-элементы и добавлять их в дерево визуального представления, удалять или редактировать существующие элементы дерева визуального представления.

Пример приложения Silverlight, взаимодействующего с JavaScript

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

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Silverlight</title>
    <script src="scripts/Microsoft.Graphics.Silverlight.js" type="text/ecmascript"></script>
    <script src="scripts/example.Graphics.Silverlight.js" type="text/ecmascript"></script>
    <script type="text/ecmascript">
        example.Instrument = {};
        example.Instrument.Pointer = {};
        example.Instrument.Pointer.Rotation = {};
        example.Instrument.Pointer.Storyboard = {};
        example.Instrument.Pointer.Animation = {};

        function onLoadPage() {
          var canvas = new example.Graphics.Silverlight.Canvas();
          canvas.onLoad = onCanvasReady;
          canvas.onError = onCanavsError;

          canvas.createCanvas("silverlightPlugin", 384, 384, 
                              "silverlightContainer");
        }

        function onCanavsError(sender, args) {
            alert(args.errorMessage + "\nLine " + args.lineNumber + 
                  " position " + args.charPosition);
        }

        function onCanvasReady(control, context, rootElement) { }

        function onCanvasLoaded(sender, args) {
            example.Instrument.Pointer.Rotation = 
                sender.FindName("PointerRotation");
            example.Instrument.Pointer.Storyboard = 
                sender.FindName("PointerAnimationStoryboard");
            example.Instrument.Pointer.Animation = 
                sender.FindName("PointerAnimation");
            setTimeout(demo, 2000);
        }

        function demo() {
            var a = Math.floor(Math.random() * 240) - 120;

            example.Instrument.Pointer.Animation.From = 
                example.Instrument.Pointer.Rotation.Angle;
            example.Instrument.Pointer.Animation.To = a;
            example.Instrument.Pointer.Storyboard.begin();

            setTimeout(demo, 5000);
        }
    </script>
  </head>
  <body onload="onLoadPage()">
    <div id="silverlightContainer"></div>
    <script id="xaml" type="text/xaml">
      // Код Silverlight, встроенный в контейнер object
      <Canvas 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        x:Name="InstrumentCanvas" 
        Loaded="onCanvasLoaded"
      >
        <Ellipse x:Name="BackFace" Width="336" Height="336" 
            Canvas.Left="24" Canvas.Top="24" 
            StrokeThickness="8" StrokeLineJoin="Round" 
            Stroke="#FF880000" Fill="transparent">
        </Ellipse>

        <Image x:Name="FaceBackgroundImage" 
            Source="images/gauge.ticks.png" />

        <Path x:Name="Path" Width="24" Height="180" 
            Canvas.Left="180" Canvas.Top="48" 
            Stretch="Fill" 
            StrokeThickness="2" StrokeStartLineCap="Round" 
            StrokeEndLineCap="Round" StrokeLineJoin="Round" 
            Stroke="#FFD10000" Data="F1 M 40,0 L 60,0 L 100,100 L 50,102 L 0,100 Z"
        >
          <Path.Fill>
            <LinearGradientBrush StartPoint="0.0,0.5" EndPoint="1.0,0.5">
              <LinearGradientBrush.GradientStops>
                <GradientStop Color="#FFD30606" Offset="0.0"/>
                <GradientStop Color="#FF690303" Offset="0.7"/>
                <GradientStop Color="#FF000000" Offset="1.0"/>
              </LinearGradientBrush.GradientStops>
            </LinearGradientBrush>
          </Path.Fill>
          <Path.RenderTransform>
            <RotateTransform x:Name="PointerRotation" Angle="0" CenterX="12" CenterY="144" />
          </Path.RenderTransform>
          <Path.Triggers>
            <EventTrigger RoutedEvent="Rectangle.Loaded">
              <BeginStoryboard>
                <Storyboard x:Name="PointerAnimationStoryboard">
                  <DoubleAnimation x:Name="PointerAnimation" 
                      Storyboard.TargetName="PointerRotation" 
                      Storyboard.TargetProperty="Angle" 
                      From="-120" To="120" Duration="0:0:1" 
                      RepeatBehavior="1x" AutoReverse="false"/>
                </Storyboard>
              </BeginStoryboard>
            </EventTrigger>
          </Path.Triggers>
        </Path>
        <Ellipse x:Name="PointerInnerHub" 
            Width="48" Height="48" 
            Canvas.Left="168" Canvas.Top="168" 
            StrokeThickness="2" StrokeLineJoin="Round" 
            Stroke="#FF000000">
          <Ellipse.Fill>
            <RadialGradientBrush RadiusX="0.5" RadiusY="0.5" Center="0.5,0.2" GradientOrigin="0.5,0.5">
              <RadialGradientBrush.GradientStops>
                <GradientStop Color="#FF202020" Offset="0.0"/>
                <GradientStop Color="#FF000000" Offset="1.0"/>
              </RadialGradientBrush.GradientStops>
            </RadialGradientBrush>
          </Ellipse.Fill>
        </Ellipse>
      </Canvas>
    </script>
  </body>
</html>
Листинг 6.3.

Результат работы показан на рис. 6.1

Пример взаимодействия кода JavaScript и Silverlight

увеличить изображение
Рис. 6.1. Пример взаимодействия кода JavaScript и Silverlight

Необходимо разместить в каталоге /scripts файл example.Graphics.Silverlight.js следующего содержания:

if (typeof example != "object") 
  var example = { _example: this };

example.Graphics = {};
example.Graphics.Silverlight = {};

example.Graphics.Silverlight.Canvas = function() {
 _canvas = this;

 this.createCanvas = function(pluginId, pixelWidth, pixelHeight, containerId) 
 {
   Silverlight.createObjectEx(
   {
     source: "#xaml",
     parentElement: document.getElementById(containerId),
     id: pluginId,
     properties:
     {
       width: pixelWidth,
       height: pixelHeight,
       background: "transparent",
       framerate: "24",
       isWindowless: "true",
       inplaceInstallPrompt: false,
       version: "1.0"
     },
     events:
     {
       onLoad: _canvas.onLoad,
       onError: _canvas.onError
     }
   });
 }
 this.onLoad = null;
 this.onError = null;
}
Листинг 6.4.

И в том же каталоге /scripts файл Silverlight.js. Это стандартный скрипт Microsoft для размещения объектов Silverlight на веб-страницах. Кроме этого в каталоге /images размещается рисунок с делениями спидометра.

Рисунок примера "спидометр"

Рис. 6.2. Рисунок примера "спидометр"

Можно видеть, как код JavaScript вызывает методы PointerRotation, PointerAnimationStoryboard, PointerAnimation, а также, код XAML приложения Silverlight вызывает функцию JavaScript onLoadPage(). Эта функция дает доступ JavaScript к методам Silverlight, регистрируя объект Silverlight на странице как объект, поддерживающий сценарии.

function onLoadPage() 
{
   var canvas = new example.Graphics.Silverlight.Canvas();
   canvas.onLoad = onCanvasReady;
   canvas.onError = onCanavsError;
   canvas.createCanvas("silverlightPlugin", 384, 384, 
                       "silverlightContainer");
}

К недостаткам во время разработки можно отнести лишь то, что Visual Studio не генерирует прокси-класс для функций JavaScript и поэтому невозможно пользоваться инструментом IntelliSense.

< Лекция 5 || Лекция 6: 1234 || Лекция 7 >