始めよう!Silverlight

第3回 メッセージカードアプリを作ってみよう

この記事を読むのに必要な時間:およそ 6.5 分

card.jsの作成

土台となるファイルの作成が完了しました。続いてはメッセージカードを表示する部分を作成していきます。まずは以下の内容をcard.jsとして保存してください。

if(typeof sample == "undefined") var sample = {};

(function(){
//[1]

sample.card = function(plugin){
//[2]
};

})();

[1]と[2]の部分にコードを記述していきます。少し長めのコードになりますので,これ以降はコードを記載する部分として[1]を「[function]の中⁠⁠,[2]を「[sample.card]の中」と記載します。

作成したcard.jsをindex.htmから呼び出すようにしておきます。

<script type="text/javascript" src="Silverlight.js"></script>
<script type="text/javascript" src="card.js"></script>
<script type="text/javascript" src="index.htm.js"></script>

メッセージカードのXAML

メッセージカードを表示するためには,メッセージカードのXAMLを実行時に読み込んでオブジェクトを生成し,app.xamlで記述したルート要素のCanvasに追加します。XAMLを実行時に読み込んでオブジェクトを生成するためには以下のcreateFromXaml関数を使用します。

var rectangle = plugin.content.createFromXaml("<Rectangle />");

ここでのpluginはSilverlightのプラグインオブジェクトを指しています。Silverightを表示しているHTMLタグのことで,Silveright.createObjectEx関数で指定したidを用いて,document.getElementByID関数で取得できます。また,SilverightのオブジェクトのgetHost関数でも取得できます。

では,メッセージカードのXAMLを文字列として変数に格納します。[function]の中に以下を記述してください。

var cardXaml = 
"<Canvas xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' " +
  "Width='200' Height='150'>" +
  "<Rectangle Width='200' Height='150' Fill='#FF727272' Opacity='0.3' />" +
  "<Rectangle Width='194' Height='144' Canvas.Left='3' Canvas.Top='3'>" +
    "<Rectangle.Fill>" + 
      "<LinearGradientBrush EndPoint='0.7,1.2' StartPoint='0.2,-0.2'>" + 
      "<GradientStop Color='#FFCCCCCC' Offset='0' />" + 
      "<GradientStop Color='#FFFFFFFF' Offset='1' />" + 
      "<GradientStop Color='#FFFFFFFF' Offset='0.3' />" + 
    "</LinearGradientBrush>" +
    "</Rectangle.Fill>" +
  "</Rectangle>" +
  "<Rectangle Opacity='0.5' Width='188' Height='30' Fill='#FF9F9F9F' " +
    "RadiusX='7.5' RadiusY='7.5' Canvas.Left='6' Canvas.Top='6' />" +
    "<Rectangle Width='186' Height='28' RadiusX='7.5' RadiusY='7.5' " + 
    "Canvas.Left='7' Canvas.Top='7'>" +
    "<Rectangle.Fill>" + 
      "<LinearGradientBrush EndPoint='0.5,0' StartPoint='0.5,1'>" + 
        "<GradientStop Color='#FFE67D00' Offset='0' />" +
        "<GradientStop Color='#FFFFB55E' Offset='1' />" +
      "</LinearGradientBrush>" + 
    "</Rectangle.Fill>" + 
  "</Rectangle>" + 
  "<TextBlock Width='175' Height='25' Canvas.Left='12' " + 
    "Canvas.Top='10' TextWrapping='NoWrap' x:Name='cardtitle{id}' />" +
  "<TextBlock Width='186' Height='100' Canvas.Left='6' " +
    "Canvas.Top='40' TextWrapping='Wrap' x:Name='cardmessage{id}'>" +
    "<TextBlock.Clip>" +
      "<RectangleGeometry Rect='0, 0, 186, 100' />" + 
    "</TextBlock.Clip>" + 
  "</TextBlock>" +
"</Canvas>";

最後のほうにある2つのTextBlockに設定されているx:Name属性の値の最後が{id}という文字になっています。これは同じNameの値をもつオブジェクトを複数追加できないため,実行時にサフィックスと置き換えるためのプレースホルダーになります。

メッセージカードの表示

では,メッセージカードを画面に表示するまでのコードを追加していきます。手順としては以下のようになります。

  • サフィックスの取得
  • XAMLの読み込み
  • オブジェクトの追加

まず,サフィックスの取得ですがこれは連番を取得するようにします。0からカウントアップしていく形で,すでにその値をNameにもつオブジェクトがないかを調べ,ない場合は,その値を使用します。オブジェクトがあるかどうかを調べるためには以下のfindName関数を使用します。findName関数は指定された値のNameをもつオブジェクトがある場合は,そのオブジェクトを返します。ない場合はnullを返します。

var obj = plugin.content.findName("cardtitle");

[function]の中に,getSuffixValueという変数で関数を作成します。引数には上記のfindName関数を呼べるように,Silverlightのプラグインオブジェクトを渡します。

var getSuffixValue = function(plugin){
  var counter = 0;
  while(true){
    if(plugin.content.findName("cardtitle" + counter) == null){
      return counter.toString();
    }
    counter++;
  }
}

上記のコード,実はJavaScriptのNumber型の限界まで同じNameがあった場合に,例外が発生してしまいます。しかも結構な時間待たされてから例外が発生することになります。本来であれば別なサフィックスの取得の仕方や,途中であきらめるコードが必要になるのですが,今回の場合は,メッセージカードアプリに限定しおり,かつそれほど枚数を作成しないということからよしとしておきます。

続いて,XAMLを読み込んでオブジェクトを作成します。前述したXAMLの文字列が設定してあるcardXaml変数と,createFromXaml関数を使用します。[function]の中にcreateCardObjectという変数で関数を作成します。引数にはcreateFromXamlを呼べるようにSilverlightプラグインオブジェクトと,cardXamlのプレースホルダーを置換するためのサフィックスを渡します。

var createCardObject = function(plugin, suffix){
  var cardObject = 
    plugin.content.createFromXaml(cardXaml.replace(/{id}/g, suffix));
  plugin.content.root.children.add(cardObject);
  return cardObject;
}

上記,2つの関数を呼び出すコードを[sample.card]の中に記述します。

sample.card = function(plugin){
  var suffix = getSuffixValue(plugin);
  var cardObject = createCardObject(plugin, suffix);
};

最後に,上記のsample.cardを呼び出すコードを追加してHTMLのボタンが押された時に呼び出せば,メッセージカードが画面に表示されます。index.htm.jsに以下の関数を追加してください。

function createNewCard(){
  var plugin = document.getElementById("agControl");
  var card = new sample.card(plugin);
}

createNewCard関数では最初にSilverlightプラグインのオブジェクトを取得しています。次にsample.cardを実行しているのですが,ここではsample.cardを続く処理としてオブジェクトで扱いたいのでコンストラクタ呼び出しにしています。

HTMLのボタンがクリックされた時にcreateNewCardが呼び出されるようにして,メッセージカードの表示の完成です。以下のようにindex.htmのボタンのコードを修正してください。

<button onclick="createNewCard();">Create</button>

著者プロフィール

丸山和秀(まるやまかずひで)

株式会社アークウェイ システムクリエイター。趣味はドラム。社会人になりたてのころは職業はドラマーだと豪語していたが,いつのまにかシステム開発の楽しさにのめりこみ,仕事内容が職業になっていた。パッケージベンダにて金融向けパッケージソフトの開発を行うSEを経て現職へ。現在は研究開発としてRIAに取り組み中。