ASP.NETとSilverlightで作るドキュメント管理アプリ その2

では、プロジェクトを作っていく。

ソリューション構成

Visual Studuio 2008で以下のソリューションとプロジェクトを作成する。

「SLDoc」プロジェクトは「ASP.NET Web アプリケーション」で作成し、「SLDoc.UI.Silverlight」プロジェクトは「Silverlight アプリケーション」プロジェクトで作成する。それぞれの役割は説明するまでもないだろう。

まずはテーマファイルから

ASP.NETアプリを作る時は、まずテーマファイルを作ることにしている。テーマファイルを使うとASP.NETのサーバーコントロールに暗黙的にスタイルを設定できるので重宝するから作っておいて損はない。

「Default.skin」ファイルと「Default.css」ファイルを追加した。中身はそのままで変更はしない。

このままではテーマが適用されないので「Web.config」ファイルにテーマの設定を追加しておく。

Web.config
<configuration>
    ....
   <pages theme="Default">
   </pages>
   ....
</configuration>

「pages」要素の「thema」属性に「Default」と設定しておく。

サイト全体のレイアウト

次はサイト全体のレイアウトを決めていく。これには当然ながらマスタページを使う。

「Shared」というフォルダを作り、その下に「Default.master」というマスタページを追加する。とりあえず、サイトのヘッダ部分から作っていく。

~/Shared/Default.master

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Default.master.cs" Inherits="SLDoc.Shared.Default" %>

<!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">
<head runat="server">
  <title>SLDoc</title>
  <style type="text/css">
      body
      {
          width: 90%;
          margin: 0px auto;
      }
      #header
      {
          margin-bottom: 5px;
          border-bottom: solid 1px silver;
      }
      #logo
      {
          font-size: 60px;
      }
      #menu
      {
          position: absolute;
      }
      #status
      {
          text-align: right;
      }
  </style>
  <asp:ContentPlaceHolder ID="head" runat="server">
  </asp:ContentPlaceHolder>
</head>
<body>
  <form id="form1" runat="server">
  <div style="display: none;">
      <asp:ScriptManager runat="server">
      </asp:ScriptManager>
  </div>
  <div>
      <div id="header">
          <div id="logo">SLDoc</div>
            
          <div id="menu">
              <asp:Menu runat="server" DataSourceID="SiteMapDataSource1" Orientation="Horizontal">
              </asp:Menu>
          </div>
            
          <div id="status">
              <asp:LoginName runat="server" FormatString="ようこそ {0} さん" />
              &nbsp;|&nbsp;
              <asp:LoginStatus runat="server" />
          </div>
      </div>
      <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
      </asp:ContentPlaceHolder>
        
      <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="False" />
  </div>
  </form>
</body>
</html>

ロゴとナビゲーションメニュー、ログインステータスなんかを表示している。ASP.NETについての解説は本題ではないので割愛させて頂く。

[追記]
ScriptManagerを忘れていたので追加した。

プレビュー

あと、ナビゲーションメニューに表示するデータの元になるサイトマップファイルの内容が以下。

~/Web.sitemap
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
  <siteMapNode>
      <siteMapNode url="~/Default.aspx" title="ドキュメント管理" />
      <siteMapNode url="~/Admin/Users.aspx" title="ユーザ管理" />
  </siteMapNode>
</siteMap>

テーマファイルにも変更を加えたので記載しておく。

~/App_Themes/Default/Default.skin
<asp:Menu runat="server">
  <StaticMenuItemStyle ItemSpacing="4" />
</asp:Menu>

<asp:LoginName runat="server" Font-Size="Small" />

マスタページはこれで完成なので、スタートページ(Default.aspx)をこのマスタページから派生させておく。既に存在する「Default.aspx」ファイルを削除して、新しく「Web コンテンツ フォーム」形式で「Default.aspx」ファイルを追加しておけばいい。

では、「Default.aspx」に変更を加えていく。とりあえず左側のツリーと右側のSilverlightコンテンツを追加してみる。

~/Default.aspx
<%@ Page Language="C#" MasterPageFile="~/Shared/Default.Master" AutoEventWireup="true"
  CodeBehind="Default.aspx.cs" Inherits="SLDoc.Default" %>

<%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls"
  TagPrefix="asp" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">

  <script type="text/javascript">
      function onPluginLoaded(s) {
      }
  </script>

  <style type="text/css">
      #main
      {
      }
      #side
      {
          position: absolute;
          width: 300px;
      }
      #content
      {
      }
  </style>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
  <div id="main">
      <div id="side">
          <asp:TreeView runat="server" ID="folderTree" ShowLines="True">
          </asp:TreeView>
      </div>
      <div id="content">
          <asp:Silverlight runat="server" ID="xaml1" Width="100%" Height="100%" OnPluginLoaded="onPluginLoaded"
              Source="~/ClientBin/SLDoc.UI.Silverlight.xap" Windowless="True" />
      </div>
  </div>
</asp:Content>

プレビュー

見ての通り左側のツリービューを「position: absolute」にして、右側のSilverlightコンテンツをがっつりかぶせている。このようにする理由はSilverlightコンテンツが左側のHTMLコンテンツを完全に制御下におけるようにする(例えば触れなくしたりとか)ためだ。

通常はこのように配置するとHTMLコンテンツがSilverlightコンテンツに完全に隠れてしまうが、Silverlightサーバーコントロールの「Windowless」プロパティをtrueにする事で、HTMLコンテンツをSilverlightコンテンツの上にオーバーラップさせる事ができる。

<asp:Silverlight runat="server" ID="xaml1" Width="100%" Height="100%" OnPluginLoaded="onPluginLoaded"
   Source="~/ClientBin/SLDoc.UI.Silverlight.xap" Windowless="True" />

また、「OnPluginLoaded」プロパティにJavaScriptのコールバック関数を指定しているが、これについては後述する。

To be continued...

ソース