Silverlight 2 開発のバリエーション
Silverlight のサンプルを見ていると、ものによって書き方が違って混乱しがち。
1つのサンプルをいくつもの書法で書いておくと、頭の中で変換ができるようになるので学習が進みやすい。
以下、Silverlight 2.0 Beta 1 SDK + Chiron.exe で開発する前提。導入方法は
- Silverlight 2 SDK+JavaScriptで無償の開発環境を作る #1 [環境整備編] (Neutral Scent)
- 始めよう!Silverlight:第6回 Dynamic SilverlightでHello world|gihyo.jp … 技術評論社
あたりを参考に。
基本形
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(){}}
として独自のエラーハンドラを指定するとよい。