Silverlightで作る付箋紙アプリ その1

最近Web上で共有するような付箋紙アプリをちらほら見かけるようになった。大抵の場合Ajaxで実装されていて、非常によくできているので感心してしまう。

こういうおもしろいアプリを触っていると自分でも作ってみたくなるのがプログラマの性ということで、最近はまっているSilverlightで作ってみることにした(というかもう作ったんだけどね)。

はじめに

まずは仕様から考える。

仕様
  • 画面をダブルクリックするとその位置に新しく付箋を貼り付けられる。
  • 付箋を画面上に自由にペタペタ貼れて、自由に剥がせる。
  • 付箋に書き込んだテキスト、サイズ、位置情報はサーバー上に記憶する。
  • 付箋の色、スキンを自由に変えることができる。
画面イメージ


こういうのを画面上にわんさか貼ることができる。

開発環境

以下の記事を参考にして、「MvcWebApplicationProjectTemplateP2.cs.zip」というプロジェクトテンプレートを使えるようにしておく。

プロジェクトの準備

Silverlight Application」プロジェクトを新規作成する。プロジェクト名は「Fusen」にする。
「Generate an HTML test page to host Silverlight within this project」を選択して、SilverlightをホストするためのWebプロジェクトは作らないようにしておく。

次に「ASP.NET MVC Web Application」プロジェクトを新規作成して追加する。プロジェクト名は「Fusen.Web」にする。

現在のツリー


掃除

このプロジェクトには要らないファイルが初めから色々追加されているので、まずはそれを削除する。

  • [Content]
  • [Views]/[Home]/About.aspx
  • [Views]/[Home]/Index.aspx
  • [Views]/[Shared]

次に「Web.config」が設定項目が多すぎて、なにがなにやらわからない状態なので必要最低限の設定だけに変更する。

Web.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <compilation debug="true">
        </compilation>

        <customErrors mode="RemoteOnly">
        </customErrors>

        <pages>
            <controls>
                <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add tagPrefix="asp" namespace="System.Web.UI.SilverlightControls" assembly="System.Web.Silverlight, Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            </controls>
        </pages>

        <httpHandlers>
            <remove verb="*" path="*.asmx"/>
            <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
        </httpHandlers>

        <httpModules>
            <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        </httpModules>

    </system.web>

    <system.codedom>
        <compilers>
            <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
                <providerOption name="CompilerVersion" value="v3.5"/>
                <providerOption name="WarnAsError" value="false"/>
            </compiler>
        </compilers>
    </system.codedom>
</configuration>

Views/Web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <httpHandlers>
            <remove verb="*" path="*.aspx" />
            <add path="*.aspx" verb="*" type="System.Web.HttpNotFoundHandler" />
        </httpHandlers>
    </system.web>
</configuration>

IIS7.0を使う場合は「system.webServer」の項目が必要になるので残しておくこと!!

URLルーティングの設定

URLルーティングの設定を最低限のものに変更する。

Global.asax.cs

using System;
using System.Web.Mvc;
using System.Web.Routing;

namespace Fusen.Web {
    public class GlobalApplication : System.Web.HttpApplication {
        public static void RegisterRoutes(RouteCollection routes) {
            routes.Add(new Route("Default.aspx", new MvcRouteHandler()) {
                Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index" }),
            });
        }
        protected void Application_Start(object sender, EventArgs e) {
            RegisterRoutes(RouteTable.Routes);
        }
    }
}

この設定だと「Default.aspx」というURLにアクセスが来たら、「HomeController」の「Index」というメソッド(アクション)が呼び出されることになる。

Silverlightプロジェクトとの関連付け

WebプロジェクトとSilverlightプロジェクトを関連付ける。

  1. 「Fusen.Web」プロジェクトのプロパティを開いて、「Siverlight リンク」タブを選択する。
  2. 「追加」ボタンをクリックすると以下の画面が表示されるので、「Add atest page that references the control」のチェックをはずしてから「Add」ボタンをクリックする。

関連付けに成功すると、Webプロジェクトに「ClientBin」というフォルダが作られて、その中にSilverlightコンテンツをまとめたXAPファイルが置かれているはず。

次にSilverlightコンテンツを表示するためのWebフォームを追加する。

「Views/Home」フォルダに「Index.aspx」というファイル名で「Web フォーム」を新規作成して、以下のように変更する。

Views/Home/Index.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="Fusen.Web.Views.Home.Index" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" style="height: 100%;">
<head id="Head1" runat="server">
    <title>付箋紙 for Silverlight</title>
</head>
<body style="height: 100%;">
    <form id="form1" runat="server" style="height: 100%;">
		<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
		<div style="height: 100%;">
			<asp:Silverlight ID="Silverlight1" runat="server"
				Height="100%" Width="100%" Source="~/ClientBin/Fusen.xap" Version="2.0" />
		</div>
    </form>
</body>
</html>

解説

タイトルを「付箋紙 for Silverlight」に変える。

ScriptManagerコントロールSilverlightコントロールツールボックスからDrag&Dropで追加する。ScriptManagerコントロールは必ず一番最初に追加する必要があるので注意!!

<asp:Silverlight ID="Silverlight1" runat="server"
            Height="100%" Width="100%" Source="~/ClientBin/Fusen.xap" />

SilverlightコントロールはHeightとWidthをそれぞれ100%に設定しておき、SourceプロパティにSilverlightコンテンツの場所を指定しておく。

あとはこの画面を表示するためにコントローラを変更しておく。

Controllers/HomeController.cs
using System;
using System.Web;
using System.Web.Mvc;

namespace Fusen.Web.Controllers {
    public class HomeController : Controller {
        public void Index() {
            RenderView("Index");
        }
    }
}

「Index」メソッドの中でRenderViewメソッドを呼び出しているだけ。これで「Views/Home/Index.aspx」が表示されることになる。

おっと、忘れてた。RenderViewメソッドで表示することができるWebフォームは「System.Web.UI.Page」からではなく、「System.Web.Mvc.ViewPage」から派生する必要があるので、そのように変更しておく。

Index.aspx.cs
using System;

namespace Fusen.Web.Views.Home {
    public partial class Index : System.Web.Mvc.ViewPage {
        protected void Page_Load(object sender, EventArgs e) {
        }
    }
}

ここまでで一度ビルドして、実行してみる。

以下のように何も無い真っ白な画面が表示されれば成功。

適当なところで右クリックしたら「Silverlightの構成」って表示される。

では、次回から本格的に作っていく。