インクリメンタルナビゲーションフレームワークの構築
私はこのThe Encephalitis SocietyのWebサイトのインクリメンタルナビゲーションをデザインするときに、コンポーネント化された、再利用可能なモデルがあったらいいなと思いました。そうすれば、誰もがこのようなナビゲーションシステムを他のASP.NET Webサイトに応用できます。そこでTheseusというフレームワークを作成しました(使用言語はC#です)。ギリシャ神話で迷宮のミノタウロスを退治したテーセウスが名前の由来になっています。Theseusフレームワークおよびデモ用Webアプリケーションは、この記事の冒頭のリンクからダウンロードできます。
Theseusは5つのファイルで構成されています。ファイル名を見れば、それぞれの役割が分かると思います。
マスターページに組み込むUIを提供する2つのユーザーコントロール(.ascxファイル)
- /Controls/Menus/TopMenu.ascx
- /Controls/Menus/SideMenu.ascx
Theseusの主な動作を定義する2つのクラス
- /App_Code/Library/Theseus/TheseusClass.cs
- /App_Code/Library/Extensions/SiteMapExtender.cs
Theseusの定型コードをWebサイトの全ページで使えるようにするためのクラス
- /App_Code/Library/BasePages/TheseusPage.cs
このフレームワークで使用するデータは、ASP.NETのサイトマップシステムを基にしています。デモ用Webサイトは既定のサイトマッププロバイダを使う設定になっており、そのサイトマップがWeb.sitemapファイルに定義されていますが、他のサイトマッププロバイダを組み込んでもTheseusは同じように利用できます。さらに、このデモ用アプリケーションではCSS Friendly Menu and TreeView control adaptersを使用しており、スタイル定義にCSSを使っています。CSS Friendlyアダプタは、ASP.NETのTreeViewコントロールとMenuコントロールで生成されるマークアップを、<table>ではなく<ul>を使うように変更し、また、HTML要素のstyle属性ではなく、CSSクラスで定義されたスタイル情報を使います。CSS Friendly Control Adaptersの詳細については、http://www.asp.net/CssAdaptersを参照ください。
基本要素
サイトタブとセクションメニューは、どちらもASP.NETのMenuコントロールを使って実装し、TopMenus.ascxファイルで定義します。サイドメニューは、ASP.NETのTreeViewコントロールを使って実装し、SideMenu.ascxファイルで定義します。MenuコントロールとTreeViewコントロールは、それぞれのSiteMapDataSourceコントロールに宣言的にバインドされます。
SideMenu.ascxのマークアップは次のようになっています。
<asp:Panel ID="pnlSideMenu" runat="server" CssClass="SideMenuWrapper">
<h3>
<asp:Label ID="lblSideMenuHeader" runat="server" Text="..." />
</h3>
<asp:TreeView ID="tvMenu3" runat="server" DataSourceID="dsMenu3"
CssSelectorClass="SideMenu" EnableViewState="false"
OnDataBound="SideMenu_DataBound"
CollapseImageUrl="~/App_Themes/WS/Images/collapse.gif"
ExpandImageUrl="~/App_Themes/WS/Images/expand.gif"
NoExpandImageUrl="~/App_Themes/WS/Images/blank.gif">
<RootNodeStyle ImageUrl="~/App_Themes/WS/Images/blank.gif" />
</asp:TreeView>
</asp:Panel>
<asp:SiteMapDataSource runat="server" ID="dsMenu3" ShowStartingNode="false" SiteMapProvider="secureSiteMap" />
TopMenus.ascxのマークアップは、さらに簡単です。これについては、この記事の冒頭からデモ用ファイルをダウンロードして参照ください。
SideMenu.ascxのコードを次に示します。こちらもかなり単純です。サイドメニューの内容をロードするコードは、Theseusフレームワークに含まれています。SideMenu.ascxユーザーコントロールでは、LoadSideMenuメソッドを使って、TreeViewコントロールをTheseusフレームワークに引き渡すだけです。LoadSideMenuメソッドは、サイドメニューに表示するノードを追加します。SetNodeSideMenuメソッドは、DataBoundイベントハンドラから呼び出され、TreeViewの必要なノードを展開します。これらのメソッドの内部的な動作については、この記事の後の方で説明します。
public partial class SideMenu : System.Web.UI.UserControl
{
private TheseusClass Theseus;
protected void Page_Load(object sender, EventArgs e)
{
Theseus = ((TheseusPage)Page).Theseus;
Theseus.LoadSideMenu(dsMenu3, tvMenu3);
bool b = tvMenu3.Visible;
if (b)
lblSideMenuHeader.Text = Theseus.SectionMenuNode.Title;
pnlSideMenu.Visible = b;
}
protected void SideMenu_DataBound(object sender, EventArgs e)
{
Theseus.SetNodeSideMenu((TreeView)sender);
}
}
Page_Loadイベントハンドラは、必要に応じてサイドメニューにデータをロードしてノードを展開するほか、LabelコントロールlblSideMenuHeaderにセクションメニューノードのタイトルを表示します。このLabelコントロールはTheseusフレームワークには含まれていませんが、サイト固有の必要性に応じて、カスタマイズした追加情報をTopMenus.ascxユーザーコントロールとSideMenu.ascxユーザーコントロールに追加する例として提供しています。
