2008年5月29日木曜日

テキストエディタでSilverlight2 #2: XAMLについて

前回のつづき。

4. コードの説明


前回のHello Worldはこんなコードだった。

Import("System.Windows.Browser.HtmlPage");
HtmlPage.Window.Alert("Hello, World!");

では、この2行を説明しよう。

1行目のImport文にまず驚く。Import?なにそれ?しかも大文字で始まってて気持ち悪いし。その気持ちは分かるが、これは"Managed" JSだ。ぶっちゃけ.NETなもんで、我慢してください。
Silverlight2で動作するように最小限に切り詰められたMini CLR (Common Language Runtime)上で動作するDLR (Dynamic Language Runtime)がこのManaged JSを解釈し実行している。よって、.NETというかCLRとの相互運用性があるし、逆に言うと多くの機能はCLRのクラスライブラリとして提供されるので、相互運用せざるを得ない。

話を戻すと、このImport文は、CLRのクラスライブラリで提供されているクラスをManaged JSで利用するための組み込み関数だと思えばよい。ここでは、System.Windows.Browser名前空間に定義されたHtmlPageクラスを利用するためにImportしている。
なお、Javaのimport文とは異なり、Import文を書かないとそのクラスは使えない(フルネームで"System.Windows.Browser.HtmlPage"と書いてもエラーになる)。そういう意味ではjavaよりはpythonのfrom...import文と似ている。

2行目ではさっそくこのクラスを使っているのだが、どう使っているのかというと、HTMLブリッジと呼ばれる機能で、ブラウザのHTML DOMやJavaScriptにアクセスするのに使う。
HtmlPageクラスは(インスタンス化せずに使う)静的クラスであり、このクラスの静的プロパティであるWindowプロパティは、ブラウザのJavaScriptに組み込まれているwindowオブジェクトのラッパーを返すのだ。
あとはJavaScriptを知ってれば使えるはず(メソッドやプロパティが大文字で始まるという気持ち悪さを我慢すれば)。というわけで今回はwindow.alertを呼び出してみたというわけ。

5. Hello World その2


しかし、わざわざSilverlight2を動かしておいてブラウザのJavaScriptを使うなんて、意味がなさ過ぎる。なので、ちゃんと(?)Silverlight自身にHello Worldを出力させるのもやってみよう。
しかし、ここで新たに覚えなければいけないことが出てくる。XAMLだ。実は、Silverlightの描画エリアを使うためには、1つはXAMLファイルを書いておかないといけないのだ。
でも、XAMLなんか覚えたくない、書きたくないという人もいるだろうから、極力XAMLを書かない方向でこの連載記事は進めて行きたい。
ということで今回書いてもらうXAMLはこちら。ファイル名はapp.xamlとでもしておこう。

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

男は黙ってCanvasタグ1つ。ちょっと名前空間がうるさいけど、これも我慢してほしい。
XAMLにはHello, World!の文字が含まれていないことに注目。Hello, World!はManaged JSでやってみよう。

続いて、app.jsxを書き換える。

Import("System.Windows.Application");
Import("System.Windows.Controls.Canvas");
Import("System.Windows.Controls.TextBlock");
var root = Application.Current.LoadRootVisual(new Canvas(), "app.xaml");
var tb = new TextBlock();
tb.Text = "Hello, World!";
root.Children.Add(tb);

これで完成。実行は前回と同様、chiron /b でよい。
Silverlight HelloWorld 2

6. コードの説明


今度のapp.jsxは7行。順に説明する。

1..3行目はImport文。これは説明してある。ただ今回インポートするクラスは前回とは違うものになっている。ApplicationクラスCanvasクラスTextBlockクラスだ。
Applicationクラスは、Silverlight2アプリケーションのエントリポイントとなり、アプリケーションの動作を決定するクラスだ。動的言語を使わずに(C#などで)開発する場合はこのクラスを継承してアプリケーションを作ることになるが、動的言語の場合はDLRがうまくやってくれるので問題ない。

4行目。DLRが用意してくれたApplicationクラスのインスタンスを取得し、LoadRootVisualメソッドを呼ぶ。このメソッドでSilverlight2の描画エリアを初期化する。第1引数は描画エリアのルートとなるUI要素、第2引数はルートのUI要素を初期化するXAMLファイルだ。今回はCanvasタグだけを持つapp.xamlファイルを指定する。Canvasタグ以外は何もないんだから、このxamlファイルは無くてもいいんじゃないかと思うが、無いとエラーになるので仕方なく指定する。ちなみに戻り値は第1引数で指定したオブジェクトが帰ってくる。今回はCanvasオブジェクトだ。

5..7行目は想像が付くだろう。テキストを描画するためのTextBlockオブジェクトをインスタンス化し、"Hello, World!"という文字列を指定し、CanvasオブジェクトのChildrenプロパティ(UI要素のコレクション)に追加している。

何でCanvasオブジェクトにDraw○○みたいなメソッドが用意されてないんだ?と疑問に思った人もいるかもしれない。
でもこれは、Mini CLR上でUI要素を拡張して独自のコントロールを作って再利用するのをやりやすくするためのモデルなのだ。
それにしてもUI要素をコードで追加していくのは面倒だが、こっちはXAMLで解決するというのが設計方針のようだ。今回はルート要素を表現するXAMLしか書かなかったが、実際には各種の要素を入れ子にしたXAMLを書くのが普通であり、そのXAMLを適用すれば自動的にオブジェクトツリーが形成されるようになっている。そのあたりのことは次回以降に。

0 件のコメント:

コメントを投稿