Silverlight 2 開発のバリエーション

Silverlight のサンプルを見ていると、ものによって書き方が違って混乱しがち。

1つのサンプルをいくつもの書法で書いておくと、頭の中で変換ができるようになるので学習が進みやすい。

以下、Silverlight 2.0 Beta 1 SDK + Chiron.exe で開発する前提。導入方法は

あたりを参考に。

基本形

HTML の基本形

object タグで埋め込む方法。一番シンプルなのがこれ。

<body>
  <object data="data:application/x-silverlight,"
    type="application/x-silverlight"
    width="100%" height="100%">
    <param name="source" value="app.xap" />
  </object>
</body>

debug を有効にするには、initParams を利用するとよい。

<body>
  <div id="out"></div>

  <object data="data:application/x-silverlight,"
    type="application/x-silverlight"
    width="100%" height="100%">
    <param name="source" value="app.xap" />
    <param name="initParams" value="debug=true,reportErrors=out" />
  </object>
</body>

エラーがあると、<div id="out"> タグの中にエラーが書き出される。

XAML の基本形

app/app.xaml に作成。100×100 の赤い四角を (0, 50) の位置に配置している。

<Canvas
  xmlns="http://schemas.microsoft.com/client/2007"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="System.Windows.Controls.Canvas">
  <Rectangle Canvas.Top="50" Width="100" Height="100"
    Fill="Red"/>
</Canvas>

Y座標が Canvas.Top プロパティで指定するのがちょっと違和感ある。Canvas クラスが処理をするから、こういう書き方をするらしい。

スクリプトの基本形

app/app.js を作成する。これが xap のエントリポイントとなる。

Import("System.Windows.Application")
Import("System.Windows.Controls.Canvas") 

function App() {
   this.scene = Application.Current.LoadRootVisual(new Canvas(), "app.xaml")
}
App.prototype.start = function() {
}

var app = new App
app.start()

LoadRootVisual() を呼び出して、XAML を読み込んでいる。

start() はあとで拡張するために空にしてある。

スクリプトのバリエーション

まずは、スクリプトをいくつかの方法で書き直してみる。

Silverlight の魅力はなんといっても DLR(Dynamic Language Runtime)。JavaScript だけじゃなく、他の言語でもスクリプトを書ける。

app.py とすれば Python、app.rb とすれば Ruby のスクリプトとして認識されるようだ。

app/app.py

Python で書いてみる。

from System.Windows import Application
from System.Windows.Controls import Canvas

class App:
   def __init__(self):
      self.scene = Application.Current.LoadRootVisual(Canvas(), "app.xaml")
   def start(self):pass

App().start()

:pass というのは空のメソッドを書くための方法。Twitter で教えてもらった。ありがたや。

実は Python 初体験。インデント狂っただけでエラーになって、「これが噂の!」と思った。

app/app.rb

Ruby で書いてみる。

include System::Windows
include System::Windows::Controls

class App
  def initialize
    @scene = Application.Current.LoadRootVisual(Canvas.new, "app.xaml")
  end
  def start
  end
end

App.new.start

XAML のバリエーション

お次は XAML をいくつかの方法で書き直してみよう。

基本形(再掲)

<Canvas
  xmlns="http://schemas.microsoft.com/client/2007"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="System.Windows.Controls.Canvas">
  <Rectangle Canvas.Top="50" Width="100" Height="100"
    Fill="Red"/>
</Canvas>

Fill プロパティを変形

Fill プロパティに Red という文字列ではなく、オブジェクトを渡してみる。

<Canvas
  xmlns="http://schemas.microsoft.com/client/2007"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="System.Windows.Controls.Canvas">
  <Rectangle Canvas.Top="50" Width="100" Height="100">
    <Rectangle.Fill>
      <SolidColorBrush Color="Red"/>
    </Rectangle.Fill>
  </Rectangle>
</Canvas>

「クラス名.プロパティ」タグの中にオブジェクトをあらわす XML を書く。

このままだと最初の例を冗長にしたにすぎないが、例えば LinearGradientBrush に書き換えれば、グラデーションで塗られるようになる。

Rectangle をスクリプトで生成

全部 XAML でやろうというサンプルが多くて嫌。スクリプトだけでやる方法を知りたい!

まずは、XAML を空っぽに。

<Canvas
  xmlns="http://schemas.microsoft.com/client/2007"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="System.Windows.Controls.Canvas">
</Canvas>

Rectangle タグをスクリプトで動的に作成してみた。

Import("System.Windows.Application")
Import("System.Windows.Controls.Canvas") 
Import("System.Windows.Shapes.Rectangle") 
Import("System.Windows.Media.*") // Colors, SolidColorBrush

function App() {
   this.scene = Application.Current.LoadRootVisual(new Canvas(), "app.xaml")
}

App.prototype.start = function() {
   var rect = new Rectangle();
   rect.SetValue(Canvas.TopProperty, 50);
   rect.Width = 100;
   rect.Height = 100;
   rect.Fill = new SolidColorBrush(Colors.Red);
   this.scene.Children.Add(rect);
}

var app = new App
app.start()

new Rectangle() して、プロパティを設定して、Add している。

Cnavas.Top プロパティを設定するには SetValue() メソッドを使ってる。Silverlight 1.0 のドキュメントを見ると rect["Canvas.Top"] でいけてるようなんだけど、2.0 ではエラーが出る。理由はまだよく分からない。

HTML のバリエーション

最後に HTML のバリエーションを紹介。

object タグで埋め込むのをやめて、silverlight.js を使って埋め込んでもよい。

<head>
   <script src="silverlight.js" type="text/javascript" ></script>
</head>

<body>
  <div id="container"></div>

  <script type="text/javascript">
    var controlID = "SilverlightControl"
    Silverlight.createObjectEx({
      source: "app.xap",
      parentElement: document.getElementById("container"),
      id: controlID,
      properties: {
        width:'100%', 
        height:'100%',
        version:'1.1'
      },
      events: {}
    });
  </script>
</body>

silverlight.js は SDK インストール時に C:\Program Files\Microsoft SDKs\Silverlight\v2.0\Tools に展開されている。HTML で書くよりも細かな設定ができる印象だ。いくつかの付加機能も魅力的。Flash での swfobject みたいな感じ。

その中でも素敵なのが、エラー発生時に alert でエラーの詳細をレポートしてくれる機能。

alert は嫌だよ、とかリリースするときには抑制したいよね、というときには、

events: {onError: function(){}}

として独自のエラーハンドラを指定するとよい。