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(){}}
として独自のエラーハンドラを指定するとよい。