Expression Blend 2とVisual Studio 2008でSilverlight 1.0しばりな開発

世界で多くの.NETな開発者がSilverlight 2に向き合っていると思いますが、私は、Silverlight 1.0レベルでのチャレンジを続けています。

理由としては、Silverlight 2がまだBeta 1なので・・・、というものなのですが、JavaScriptだけでもできる範囲はそれなりにあって、.NET言語を知らなくてもSilverlightを使う世界というのもきちんと知っておこうと考えているからです。

もちろんSilverlight 2になれば楽になる部分が相当あることは十分に知っています。Silverlight 2が正式なリリースを迎えてもJavaScriptベースのAPIで作られたものはそのまま動くので、Silverlight 1.0しばりというのは、かならずしも無駄ではないと思っています。
(でもそろそろ、Silverlight 2の開発環境をしっかり整えていろんなサイト構築の開発支援に備えなければいけませんが。。。)

この制約の中で作業していると、Expression Blend 2/2.5とVisual Studio 2008を行き来するのがとても便利であることを実感できます。

Blend側でオブジェクトを配置したら、必ず名前をつけるようにします。これをPage.xaml.js内では、handleLoadメソッドの中で、

this.MyObject = control.content.findName("MyObject");

という形でXAML内のオブジェクトをJavaScriptのオブジェクトに変換できます。これを癖付けると、プログラミングで利用するオブジェクトは、かならず同じプロトタイプのスコープ内で、this.MyObject の形式で参照できるようになります。Canvasだけではなく、アニメーションを実行する際のStoryboardも同様の方法で参照できるので、

this.MyStoryboard = control.content.findName("MyObject");

という形で変数に閉じ込めておけば、

this.MyStoryboard.Begin();

とすることで、いつでも実行できます。JavaScriptのprototypeをゼロから自分で書かなくても、雛形はExpression Blend 2/2.5でSilverlight 1.0用のsiteを構築した際に作られるので、そこを拡張していけばよいわけです。

イベントはどうしたらいいでしょうか。基本的に、addEventListenerメソッドとSilverlight.createDelegateメソッドを使ってマッピングしていきます。たとえば、MyCanvasという名前のCanvasにおけるマウスイベントを考えましょう。またMyCanvasがクリックされた時に実行されるアニメーションをMyStoryboardという名前のStoryboardに定義してあると仮定します。この場合、MyCanvas上で発生するマウスイベントのイベントハンドラを次のように記述できます。JavaScriptに慣れてない方でも、なんとなくこのイベント処理の流れは理解できるのではないでしょうか。

 handleLoad: function(control, userContext, rootElement) 
{
    this.control = control;
    this.MyCanvas = control.content.findName("MyCanvas");
    this.MyStoryboard = control.content.findName("MyStoryboard");
    this.MyCanvas.addEventListener("MouseMove", 
        Silverlight.createDelegate(this, this.handleMouseMove));
    this.MyCanvas.addEventListener("MouseEnter", 
        Silverlight.createDelegate(this, this.handleMouseEnter));
    this.MyCanvas.addEventListener("MouseLeave", 
        Silverlight.createDelegate(this, this.handleMouseLeave));
    this.MyCanvas.addEventListener("MouseLeftButtonDown", 
        Silverlight.createDelegate(this, this.handleMouseDown));
    this.MyCanvas.addEventListener("MouseLeftButtonUp", 
        Silverlight.createDelegate(this, this.handleMouseUp));
},
handleMouseMove: function(sender, eventArgs) 
{

},
handleMouseEnter: function(sender, eventArgs) 
{

},
handleMouseLeave: function(sender, eventArgs) 
{

},
handleMouseDown: function(sender, eventArgs) 
{

},
handleMouseUp: function(sender, eventArgs) 
{
    this.MyStoryboard.Begin();
},

このようにコードをVisual Studio 2008上で書いていくことで、アプリケーションの動きを作れます。ストーリーボードの代わりに、たとえば、

 this.MyVideo = control.content.findName("MyVideo");
 のように MediaElementを参照する変数を準備して、
 handleMouseUp: function(sender, eventArgs) 
{
    this.MyVideo.Play();
},

という形で、MyCanvas上をクリックしたらMyVideoで参照できるビデオファイルを再生する、というコードが簡単に書けます。

Blendで画面を構築する <--> Visual Studio 2008でイベントを実装する

この往復を繰り返すと、目的とするアプリケーションの完成に近づきます。 JavaScriptのprototypeが大きくなっていくのが気になるかもしれませんが、まずは、prototype内においてやりたいことを並べていくのが完成への近道だと思います。それとVisual Studio 2008を使えば、JavaScriptのデバッグが可能なので、気になる動きに対してブレークポイントを設置して、ステップ実行することもできます。
これは期待通りにプログラムが動かないときにとても便利ですが、1点だけご注意を。JavaScriptのprototypeを記述する際に、追加したメソッドの最後が,で終わってないようにしてください。
あるいは、追加したメソッドの名前のひとつ前に必ず,が入っているようにしてください。これを忘れると、Visual Studioが別のjsファイルのエラーとして例外を捕捉するのですが、そのファイルにはエラーがないので、すぐに原因がわかりません。
これを一度体験したら2度目からはすぐに対処できるのですが、最初はびっくりするので、事前知識として持っておいて損はないです。まずは簡単なところから繰り返してみるといいでしょう。もちろん、Microsoft Visual Web Developer 2008 Express Editionを使って同様のことができますので、Silverlightに興味があるけど、開発環境が・・・、と悩まれている方々にはダウンロードして利用してみてください。