|
.NET TIPS
[ASP.NET]データベースからツリー・メニューを生成するには?
山田 祥寛
2005/04/08 |
 |
|
「TIPS:[ASP.NET]TreeViewコントロールでツリー・メニューを作成するには?」では、カスタム・コントロールであるTreeViewコントロールを利用して、XMLファイル(ツリー定義ファイル)からツリー・メニューを生成する方法について紹介した。
しかし、ある程度大規模なサイトになれば、メニュー情報はコンテンツ管理と併せてデータベース上で行っているのが一般的だろう。その場合に、メニュー情報だけをわざわざXMLファイル(=ツリー定義ファイル)として管理する(この方法についての詳細は前掲のTIPSを参照)、もしくはデータベースと二重管理をしなければならないというのは、保守性/開発生産性いずれを取ってみてもうれしいことではない。
そこで本稿では、TreeViewコントロールを利用して、データベース上で管理されたデータからツリー・メニューを生成する方法について紹介する。なお、本稿のサンプルを利用するには、あらかじめ前掲のTIPSの手順に従って、TreeViewコントロールをインストールしておく、また、データベース上に以下のようなsitemapテーブルを作成しておく必要がある。
フィールド名 |
データ型 |
概要 |
url |
VARCHAR(255) |
リンク先のURL(主キー) |
title |
VARCHAR(50) |
タイトル |
target |
VARCHAR(10) |
リンク時のターゲット |
parent |
VARCHAR(255) |
親ノードのURL(urlフィールドに対応。親ノードを持たない場合には“-”をセット) |
 |
sitemapテーブルのフィールド・レイアウト |
また、sitemapテーブルには、以下の表のようなデータをあらかじめセットアップしておくこと。
url |
title |
target |
parent |
books.aspx |
新着書籍情報 |
_blank |
- |
bbs.aspx |
Q&A掲示板 |
_blank |
- |
config.aspx |
サーバサイド環境構築 |
_blank |
- |
sample.aspx |
JSP&サーブレットサンプル集 |
_blank |
books.aspx |
xml.aspx |
10日でおぼえるXML入門教室 |
_blank |
books.aspx |
e_aspnet.aspx |
ASP.NET環境設定 |
_blank |
config.aspx |
e_jsp.aspx |
JSP環境設定 |
_blank |
config.aspx |
e_j2se.aspx |
J2SE |
_blank |
e_jsp.aspx |
e_apache.aspx |
Apache |
_blank |
e_jsp.aspx |
 |
sitemapテーブルにセットするデータ(例) |
それでは、具体的なコードを見ていくことにしよう。
<%@ Page ContentType="text/html" Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Register TagPrefix="ie" Namespace="Microsoft.Web.UI.WebControls"
Assembly="Microsoft.Web.UI.WebControls" %>
<script runat="Server">
void Page_Load(Object sender, EventArgs e){
Boolean flag = SetNewNode("-", tree.Nodes);
}
// 指定されたURL(parent)を親ノードとするノード群をツリーに追加
Boolean SetNewNode(String parent, TreeNodeCollection nodes){
// 変数flagは、配下に子ノードがあるかどうかを判定するフラグ
Boolean flag = false;
SqlConnection objDb = new SqlConnection("Data Source=(local);User ID=sa;Password=sa;Persist Security Info=True;Initial Catalog=dotnet");
// パラメータparentをキーにsitemapテーブルを検索
// (parentで指定されたURLを親に持つコンテンツを抽出)
SqlCommand objCom = new SqlCommand("SELECT url,title,target FROM sitemap WHERE parent=@parent", objDb);
objCom.Parameters.Add("@parent", parent);
objDb.Open();
SqlDataReader objDr = objCom.ExecuteReader();
// 取得したコンテンツを新規ノードとしてツリーに追加
// その際、そのコンテンツが最末端でない(子ノードを持つ)場合には
// SetNewNodeメソッドを再帰的に呼び出し、同様にノードの追加を行う
while (objDr.Read()) {
TreeNode node = new TreeNode();
node.NavigateUrl = objDr.GetString(0);
node.Text = objDr.GetString(1);
node.Target = objDr.GetString(2);
// SetNewNodeメソッドがtrueを返す場合、ノード型を“Folder”に、
// falseである場合には“File”にそれぞれセット
if (SetNewNode(objDr.GetString(0), node.Nodes)) {
node.Type = "Folder";
}else{
node.Type = "File";
}
nodes.Add(node);
flag = true;
}
objDb.Close();
return flag;
}
</script>
<html>
<head>
<title>データベースからツリー・メニューを生成</title>
</head>
<body>
<form runat="Server">
<ie:TreeView id="tree" runat="Server"
SystemImagesPath="/webctrl_client/1_0/treeimages/">
<ie:TreeNodeType Type="Folder"
ExpandedImageUrl="/webctrl_client/1_0/images/folderopen.gif"
ImageUrl="/webctrl_client/1_0/images/folder.gif" />
<ie:TreeNodeType Type="File"
ImageUrl="/webctrl_client/1_0/images/html.gif" />
</ie:TreeView>
</form>
</body>
</html>
|
|
データベースから動的にツリー・メニューを生成するWebフォーム(C#版:treeview_db_cs.aspx) |
<%@ Page ContentType="text/html" Language="VB" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Register TagPrefix="ie" Namespace="Microsoft.Web.UI.WebControls"
Assembly="Microsoft.Web.UI.WebControls" %>
<script runat="Server">
Sub Page_Load(sender As Object, e As EventArgs)
Dim flag As Boolean = SetNewNode("-", tree.Nodes)
End Sub
' 指定されたURL(parent)を親ノードとするノード群をツリーに追加
Function SetNewNode(parent As String, nodes As TreeNodeCollection) As Boolean
' 変数flagは、配下に子ノードがあるかどうかを判定するフラグ
Dim flag As Boolean=False
Dim objDb As New SqlConnection("Data Source=(local);User ID=sa;Password=sa;Persist Security Info=True;Initial Catalog=dotnet")
' 仮引数parentをキーにsitemapテーブルを検索
' (parentで指定されたURLを親に持つコンテンツを抽出)
Dim objCom As New SqlCommand("SELECT url,title,target FROM sitemap WHERE parent=@parent", objDb)
objCom.Parameters.Add("@parent",parent)
objDb.Open()
Dim objDr As SqlDataReader = objCom.ExecuteReader()
' 取得したコンテンツを新規ノードとしてツリーに追加
' その際、そのコンテンツが最末端でない(子ノードを持つ)場合には
' SetNewNodeメソッドを再帰的に呼び出し、同様にノードの追加を行う
Do While objDr.Read()
Dim node As New TreeNode()
node.NavigateUrl = objDr.GetString(0)
node.Text = objDr.GetString(1)
node.Target = objDr.GetString(2)
' SetNewNodeメソッドがtrueを返す場合、ノード型を“Folder”に、
' falseである場合には“File”にそれぞれセット
If SetNewNode(objDr.GetString(0),node.Nodes) Then
node.Type = "Folder"
Else
node.Type = "File"
End If
nodes.Add(node)
flag = True
Loop
objDb.Close()
Return flag
End Function
</script>
<html>
<head>
<title>データベースからツリー・メニューを生成</title>
</head>
<body>
<form runat="Server">
<ie:TreeView id="tree" runat="Server"
SystemImagesPath="/webctrl_client/1_0/treeimages/">
<ie:treenodetype Type="Folder"
ExpandedImageUrl="/webctrl_client/1_0/images/folderopen.gif"
ImageUrl="/webctrl_client/1_0/images/folder.gif" />
<ie:TreeNodeType Type="File"
ImageUrl="/webctrl_client/1_0/images/html.gif" />
</ie:TreeView>
</form>
</body>
</html>
|
|
データベースから動的にツリー・メニューを生成するWebフォーム(VB.NET版:treeview_db_vb.aspx) |
サンプルの細かなロジックについてはコード内のコメントを参照していただくとして、ここで注目していただきたいのは、再帰的に呼び出されるSetNewNodeメソッドだ。
本サンプルでは、最上位のノード(parentフィールドが0であるノード)から順にツリーへの追加処理を行い、それぞれのノードについて子ノードが存在する場合には子ノードの追加処理を行う。そして、さらにその下位のノードが存在する場合には、孫ノードを追加する……というように、再帰的な処理を最下位のノードまで繰り返すことで、ツリー・メニューを生成しているわけだ。これによって、不特定数の階層を持つツリー情報についても、これだけコンパクトなコードで構築することができる。
前掲のTIPSと比べると、TreeViewコントロールのTreeNodeSrc属性(ツリー定義ファイルとの関連付けの設定を行う)がなくなっていることが分かる。このコードでは、ツリー定義ファイルを利用する代わりに、ページがロードされるタイミングでSetNewNodeメソッドを呼び出してツリー・メニューを構築している。
このSetNewNodeメソッドのパラメータには、TreeViewコントロール(treeオブジェクト)のNodesプロパティが指定されているが、このプロパティの値はTreeNodeCollectionクラス(Microsoft.Web.UI.WebControls名前空間)のオブジェクトだ。SetNewNodeメソッド内でこのTreeNodeCollectionオブジェクトのAddメソッドが呼び出されることで、メニュー・ツリーの項目が実際に追加されるようになっている。
以上を理解したら、さっそく、サンプル・コードを実行してみよう。データベースに格納した内容に従って、以下のような結果を得られれば成功だ。
なお、本稿ではTreeView、TreeNodeなどの各クラスの詳細については説明しない。各メソッド/プロパティに関する詳細を知りたいという方は「WebControls ASP .NET Object Reference」などを参照していただきたい。
カテゴリ:Webフォーム 処理対象:IE WebBrowserコントロール
使用ライブラリ:TreeViewコントロール(Microsoft.Web.UI.WebControls名前空間)
使用ライブラリ:TreeNodeCollectionクラス(Microsoft.Web.UI.WebControls名前空間)
関連TIPS:[ASP.NET]TreeViewコントロールでツリー・メニューを作成するには? |
|
generated by
|
|
Insider.NET 記事ランキング
本日
月間