デベロッパー
デベロッパー
AJAX SlideShowおよびTreeViewコントロールを使用してスライドショーを作成する
はじめに
Webベースのほとんどのスライドショーアプリケーションでは、部分的であれ全体的であれ、データを保存するためにデータベースが欠かせません。今回作成するアプリケーションでは、画像をディレクトリ構造から表示し、データベースは使用しません。このアプリケーションでは、ファイルシステムのナビゲーションにASP.NET 2.0 TreeViewコントロールを使用し、ディレクトリ内の画像を表示するのにAJAX 1.0 SlideShow Extender(コントロール)を使用します。必要なソフトウェア
このアプリケーションを作成するには、Microsoft Visual Studioをインストールする必要があります。私はVisual Studio 2005 Professionalを使用しました。また、http://www.asp.net/から、ASP.NET AJAX ExtensionsとAJAX Control ToolKitをダウンロードする必要もあります。これらは個々にインストールする必要があるため、両方とも入手してください。AJAXについては、Visual Studioおよび.NET Frameworkのバージョンと互換性のあるバージョンをダウンロードする必要があります。私はMicrosoft Visual Studio 2005とASP.NET 2.0を使用しているため、ASP.NET 2.0 AJAX Extensions 1.0をダウンロードしました。Control Toolkitのダウンロードは1つしかありません。Visual Studioプロジェクトではなく、IIS Webサイトから開発している場合は、そのWebサイトが適切なバージョンのASP.NETを使用していることを確認します。私のアプリケーションでは2.0を選択しています。
AJAX ExtensionsやAJAX Control ToolKitをビルドする必要がある場合もあります。ビルド版Control ToolkitのバイナリであるAjaxControlToolkit.dllが置かれている場所を覚えておく必要があるでしょう。後でこのライブラリをWebプロジェクトに参照として追加します。
アプリケーションの簡単な説明
このアプリケーションは、所定のディレクトリがあることを前提として、そのディレクトリ内の画像をSlideShowに読み込んで表示することを目的としています。このアプリケーションは、画像を表示するための単一のWebページで、2つのセクションに分かれています。ページの左側にあるのはナビゲーションで、ファイルシステムに連結されたASP.NET 2.0 TreeViewコントロールで作成されています。ページの右側にあるのは、Ajax Control Toolkitに含まれるAjax SlideShowで、画像の下にはいくつかの説明ラベルとコントロールボタンがあります。

TreeViewの構造とWebおよびファイルシステムの比較
TreeViewコントロールでは、データを階層構造でナビゲーションします。階層は任意に作成できます。TreeViewコントロールは、オペレーティングシステムのファイルシステム操作で使用するツリービューによく似ているため、どのようなファイルシステムのナビゲーションで使用するのにもふさわしいコントロールです。今回のサンプルアプリケーションのTreeViewコントロールでは、ノードごとにいくつかのプロパティを使用して各ノードを識別します。その中で特に便利なプロパティは、Text、ValuePath、およびValueの3つです。Textは、ツリーに表示する要素、つまりディレクトリ名で、たとえば「Product Images」です。Valueは、Web上での位置で、たとえば「/Images/Product/」です。ValuePathは、TreeViewコントロールが必要とするノードの位置で、たとえば「/Images/|/Images/Product/」です。
パイプ文字「|」は、PathSeparatorで設定します。既定の「/」をそのまま使用するのではなく、PathSeparatorを「|」に設定することが重要です。そうしないとValuePathが「/Images///Images/Product/」のようになってしまい、紛らわしくなります。ValuePathを使用してノードを再度検索するときには、TreeViewコントロールは既定のPathSeparatorを使用してノードを検索しません。このアプリケーションでは、ディレクトリとその子ディレクトリを探すために、Server.MapPathを使用して、Web上での位置「/Images/Product/」を「c:¥project¥Images¥Product」に変換します。単純なことにも見えますが、デバッグ時にはこれらのアドレスの違いを区別できる必要があります。
このアプリケーションの場合、SlideShowコントロールは、ContextKeyで指定された場所にある画像を表示します。これはTreeViewのValueプロパティと同じ値です。SlideShowで使用する画像のある場所が変更されない限り、ContextKeyを使用する必要はありません。
| コントロール | 場所の例 |
| TreeView.SelectedNode.Text | Product |
| TreeView.SelectedNode.Value | /Image/Product/ |
| TreeView.SelectedNode.ValuePath | /Image/|/Image/Product/ |
| SlideShow.ContextKey | /Image/Product/ |
スライドショーサービスの概要
Default.aspxページ上のSlideShowエクステンダは、SlideService.asmxから返されるスライドの配列を使用します。この配列には、スライドショーに表示する画像の場所、タイトル、および説明が格納されています。次のXMLは、返されるSlide配列の例を示しています。<?xml version="1.0" encoding="utf-8"?> <ArrayOfSlide xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://MYDOMAINHERE.com/"> <Slide> <ImagePath>/images/images_15seconds.jpg</ImagePath> <Name> images_15seconds</Name> <Description /> </Slide> <Slide> <ImagePath>/images/ images_Blue hills.jpg</ImagePath> <Name> images_Blue hills</Name> <Description /> </Slide> <Slide> <ImagePath>/images/ images_Sunset.jpg</ImagePath> <Name> images_Sunset</Name> <Description /> </Slide> <Slide> <ImagePath>/images/ images_Water lilies.jpg</ImagePath> <Name> images_Water lilies</Name> <Description /> </Slide> <Slide> <ImagePath>/images/ images_Winter.jpg</ImagePath> <Name> images_Winter</Name> <Description /> </Slide> </ArrayOfSlide>
上の「images_Bull Hills.jpg」のように、サンプルアプリケーションに付属する画像にはすべて、ファイル名の前にディレクトリ名が付いています。これはデバッグを簡単にするための工夫です。表示する画像の先頭には、選択されたノードのTreeView.Valueの値を付加する必要があります。
スライドショーサービスの要点
このサービスで唯一実行する必要があるのは、有効なWebディレクトリがあることを前提として、有効なSlide配列またはNULLを返すことです。信頼できるサービスにするために、次の処理を実行する必要があります。- Directory.Existsを使用して、Webディレクトリが存在するかどうかを確認します。
- web.configのリストの拡張子と再度比較して、画像ファイルの拡張子がこのアプリケーションに有効かどうかを確認します。
- そのディレクトリで画像が見つからない場合は、web.configに定義されている有効な画像を返します。
Webアプリケーションの作成
Visual Studioで、AJAX対応Webアプリケーションを新規作成します。
SlideService.asmxの作成
SlideService.asmxという名前のWebサービスを追加します。あらかじめ用意されている「Hello World」的な関数を、次のように変更します。
[WebMethod]
public AjaxControlToolkit.Slide[] GetSlides(String contextKey)
{
return null;
}
GetSlidesです。パラメータは、String型のcontextKeyです。contextKeyは、どのような方法でも使用できます。このパラメータは、呼び出し元AJAXコントロールからWebサービスに情報を渡すのに使用します。このアプリケーションでは、このパラメータを使用して、スライドショーのソースディレクトリを指定します。戻り値は、スライドの配列です。AJAX SlideShowコントロールがこのシグネチャを探すときには、シグネチャの大文字と小文字が厳密に区別されます。この構文を変更するとサービスが呼び出されなくなるので、変更しないでください。次のキーをWeb.Configに追加します。
<add key="SlideServiceNoImagesFoundLocation"
value="NoImagesFound.jpg"/>
<add key="SlideServiceValidImageExtensions" value="jpg,gif,bmp,ico"/>
上の例では、「NoImagesFound.jpg」という名前の画像を指定しています。この画像は、この記事のダウンロードファイルに含まれています。アプリケーションには次のように表示されます。

GetSlides()から呼び出されます。private AjaxControlToolkit.Slide[] GetNoImagesFoundDirectory() { AjaxControlToolkit.Slide[] slides = new AjaxControlToolkit.Slide[1]; // get image from web.config and verify it exists on file system _noImagesFoundWebLocation = System.Configuration.ConfigurationSettings.AppSettings.Get( "SlideServiceNoImagesFoundLocation"); if (!File.Exists(Server.MapPath(_noImagesFoundWebLocation))) throw new Exception("SlideService.asmx::GetNoImagesFoundDirectory - NoImagesFoundLocation found in
web.config does not exist after server.mappath - " + Server.MapPath(_noImagesFoundWebLocation)); // create slide from image slides[0] = new AjaxControlToolkit.Slide( _noImagesFoundWebLocation, "No Images Found: Please click on another directory", ""); // return slide return (slides); }
GetNoImagesFoundDirectory関数は、要素を1つだけ持つSlide配列を作成します。この関数は、Web.Configから画像ファイルの場所を取得し、実際にファイルが存在するかどうかを確認します。次に、Slide配列に画像を追加し、別のディレクトリをクリックする必要があることをユーザーに示す見出しを追加します。ここでは説明しませんが、この記事のダウンロードパッケージには、
IsImage()およびGetImageExtensionsFromWebConfig()という2つの関数もあり、GetSlides()から呼び出されます。GetSlides()関数は次のとおりです。[WebMethod] public AjaxControlToolkit.Slide[] GetSlides(String contextKey) { // get valid extensions GetImageExtensionsFromWebConfig(); // contextKey not empty if (String.IsNullOrEmpty(contextKey)) return null; // contextKey in scope if ((contextKey.IndexOf("..")>=0)) return null; // verify contextKey directory exists String mapPath = Server.MapPath(contextKey); if (!Directory.Exists(mapPath)) throw new Exception( "SlideService.asmx::GetSlides - mapPath does not exist - " + Server.MapPath(mapPath)); // get files in contextKey directory string[] fileNames = System.IO.Directory.GetFiles(mapPath); if (fileNames.Length == 0) return GetNoImagesFoundDirectory(); // create generic empty list of slides List<AjaxControlToolkit.Slide> list = new List<AjaxControlToolkit.Slide>(); String justFileName; String displayedFileTitleOnSlider; String displayedFileDescriptionOnSlider; for (int i = 0; i < fileNames.Length; i++) { if(IsImage(Path.GetExtension(fileNames[i]))) { // get complete filename justFileName = Path.GetFileName(fileNames[i]); // get title displayedFileTitleOnSlider = Path.GetFileNameWithoutExtension(fileNames[i]); // set description to empty displayedFileDescriptionOnSlider = String.Empty; // add file to list of slides list.Add(new AjaxControlToolkit.Slide(contextKey + justFileName, displayedFileTitleOnSlider, displayedFileDescriptionOnSlider)); } } return (list.ToArray()); }
GetSlides()関数は、Web.Configから有効なファイル拡張子を取得し、contextKeyが空でないことを確認し、安全性を確保するために、contextKeyがこのアプリケーションのスコープ内にあることを確認します。次に、Server.MapPathを利用してcontextKeyをWeb上での位置からディスク上の物理的な位置に変換し、それが実際に存在するかどうかを確認します。その後、該当ディレクトリ内のファイルの名前をすべて文字列配列に取り込みます。
この文字列配列にファイル名が1つも含まれていない場合は、
GetNoImagesFoundDirectory()関数を利用して画像NoImagesFoundを返します。次に、この関数は、ジェネリック型を利用して空のスライドリストを作成します。その後、ファイル名を反復処理して、有効な拡張子を検索します。有効な拡張子を持つファイル名は、スライド配列に追加していきます。ファイル名から拡張子を除いた部分を、スライドショー画像のタイトルにします。スライドショー画像の説明は空白にします。続いて、次のクラス変数を追加します。
String _noImagesFoundWebLocation; //path and file of the image //containing "No Images Found" text String _arrayOfImageExtensions; //string of valid image file //extensions without "." in the //value ex "jpg,gif" String[] _extensionList; //string array of valid image file extensions // without "." and with comma removed
using System.Web.UI.WebControls; using System.Diagnostics; using System.IO; using System.Configuration; using System.Collections.Generic;
GetSlides関数の上部にある宣言に、次の行を追加します。[System.Web.Script.Services.ScriptService()]
次の形式の結果が得られることを確認します。
<Slide> <ImagePath>/images/Blue hills.jpg</ImagePath> <Name>Blue hills</Name> <Description /> </Slide>
注意事項
スライドショーサービスから適切な形式で正しいデータが返されるまでは、次のWebページに移動しないでください。Webページをビルドしてテストする際、スライドショーサービスにバグがあったとしても通知はされません。AJAX SlideShowコントロールは、誤った方法で使用されたり、スライドショーサービスから誤った形式のデータが渡されたりしても、単に機能しないだけで、その誤りがユーザーに通知されることはありません。TreeViewの概要
TreeViewコントロールは、System.Web.UI.WebControls名前空間で提供される標準ナビゲーションコントロールです。TreeViewコントロールの既定の開始場所は、Web.ConfigのTreeViewDefaultStartLocationキーで設定されます。この場所は、TreeViewコントロールのルートになります。それ以外のノードはすべて、コードで子ディレクトリを反復処理することによって追加されます。次のコードを追加する必要があります。
- ノードが選択されているときに、そのノードのValuePathをcontextKeyとしてWebサービスに渡す。
- ノード外の位置がクエリ文字列によって渡されたときに、選択されたノードを検索し、そのValuePathをcontextKeyとしてWebサービスに渡す。
AJAX SlideShowの概要
AJAX SlideShowコントロールは、AJAXControlToolkit.dllに含まれるAJAXコントロールツールキットのメンバです。このコントロールは、Webのパスで示された場所の画像を表示します。そのため、SlideShowコントロールはスライドショーサービスがどこにあるかを認識しなければなりません。このパラメータは、Webのパスとファイル名という形式でWeb.ConfigのSlideShowWebServiceLocationキーに格納されています。SlideShowコントロールに関係するパラメータはいくつかありますが、その1つは、スライドショーで使用するスライドショーサービスの場所を指定するパラメータです。これは、Web.ConfigファイルのSlideShowDefaultLocationに格納されています。もう1つは、最初に読み込むファイルを指定するパラメータです。このパラメータを使用すると、スライドショーサービスがスライドの配列を作成している間に画像を表示できます。この値は、Web.ConfigのSlideShowDefaultLocationFirstPictureキーに格納されています。
画像を1つのディレクトリに格納している場合は、SlideShowのために必要なすべての値をコントロールのパラメータで設定できます。スクリプトやコードを追加する必要はありません。このアプリケーションではディレクトリを変更するため、一部のSlideShowパラメータを分離コードファイルで設定するようにします。
Webページの修正
default.aspxに、AJAX Script Managerを追加します。
<asp:ScriptManager ID="ScriptManager1" runat="server" />
次に、ツールボックスのナビゲーションタブからTreeControlを追加します。既定のコントロールは次のとおりです。
<asp:TreeView ID="TreeView1" runat="server"> </asp:TreeView>
<asp:TreeView ID="TreeView1" runat="server"
ExpandDepth=1
ShowExpandCollapse=true
OnSelectedNodeChanged="TreeView1_OnSelectedNodeChanged"
PathSeparator="|"
EnableViewState=true
SelectedNodeStyle-Font-Bold=true
SelectedNodeStyle-ForeColor=red
/>
Imageコントロールを追加します。SlideShowは、このコントロール内に画像を表示します。
<asp:Image ID="imgPhotos" runat="server" Height="300"
Style="width:auto; border:solid 1px #000000;" />
<cc1:SlideShowExtender ID="SlideShowExtender1" runat="server"> </cc1:SlideShowExtender>
<cc1:SlideShowExtender ID="SlideShowExtender1" runat="server"
TargetControlID="imgPhotos"
SlideShowServiceMethod="GetSlides"
SlideShowServicePath="/SlideService.asmx"
ContextKey="images/"
UseContextKey=true
AutoPlay="true"
NextButtonID="btnNext"
PlayButtonText="Play"
StopButtonText="Stop"
PreviousButtonID="btnPrev"
PlayButtonID="btnPlay"
Loop="true"
ImageTitleLabelID=lblTitle
ImageDescriptionLabelID=lblDescription
/>
SlideShowの下部に、次のラベルコントロールを追加します。
<center><asp:Label ID="lblTitle" runat=server></asp:Label> </center><br /> <asp:Label ID="LabelTreeSelectedNode" runat=server></asp:Label><br /> <asp:Label ID="LabelClickthroughURL" runat=server></asp:Label><br /> <asp:Label ID="lblDescription" runat=server></asp:Label><br /> <center> <asp:Button ID="btnPrev" Text="Prev" runat="server" /> <asp:Button ID="btnPlay" Text="Play" runat="server" /> <asp:Button ID="btnNext" Text="Next" runat="server" /> </center>
Default.aspx.cs
分離コードファイルの主な役割は、TreeViewコントロールへのデータの設定、正しいノードの検索、およびノードの選択の処理です。ファイルおよびディレクトリの管理のために、次のライブラリをdefault.aspxに追加します。
using System.IO;
Page_Load関数とTreeView1_OnSelectedNodeChanged関数です。これ以外の関数については簡単にしか触れないので、詳細はダウンロードサンプルを参照してください。Page_Load関数は次のとおりです。
protected void Page_Load(object sender, EventArgs e) { GetWebConfigSettings(); VerifyDirectoriesAndFiles(); // SET first image imgPhotos.ImageUrl = _slideShowDefaultLocation + _slideShowDefaultLocationFirstPicture; imgPhotos.AlternateText = _slideShowDefaultLocation + _slideShowDefaultLocationFirstPicture; // set web service path SlideShowExtender1.SlideShowServicePath = _slideShowWebServiceLocation; SlideShowExtender1.ContextKey = _slideShowDefaultLocation; // don't add copy of tree to tree on postback if (TreeView1.Nodes.Count == 0) PopulateTree(); // Set From QueryString or ViewState if ((!String.IsNullOrEmpty(_currentTreePathQueryStringName)) && ((Request[_currentTreePathQueryStringName] != null) || (ViewState[_currentTreePathQueryStringName] != null))) SelectNodeBasedOnQueryStringOrViewState(); // else assume first time to page else { // first time to page if (!String.IsNullOrEmpty(_slideShowDefaultLocation)) { ExpandTreePathByDirPath(); } } // set labels so that selected info is visible on page //LabelTreeSelectedNode.Text = //"<b>SlideShowExtender1.ContextKey:</b>" //+ SlideShowExtender1.ContextKey; if (String.IsNullOrEmpty(LabelClickthroughURL.Text)) { LabelClickthroughURL.Text = "<a href='mailto:?subject=Picture SlideShow from theBerrys&Body=" + HttpContext.Current.Request.Url + "?" + _currentTreePathQueryStringName + "=" + Server.UrlEncode(_slideShowDefaultLocation) + "'>Send link to this page by email</a><br>"; } }
次の2行では、SlideShowで使用する最初の画像を取得します。この画像は、スライドショーサービスが呼び出されて処理されている間に表示されます。「please wait...」という画像を使用してもかまいませんし、画像を何も表示しないという方法もあります。次の行では、スライドのリストを取得するために使用するサービスの場所をSlideShowに認識させます。
続く数行では、TreeViewコントロールにまだデータが割り当てられていない場合に限り、割り当てを行います。これはポストバックのために重要です。さらに、次のコードブロックでは、TreeViewコントロール内のどのノードを選択状態として設定する(赤で強調表示する)かをViewStateまたはQueryStringに基づいて決定します。この機能は、たとえばURLを他のユーザーに送信し、そのユーザーがリンクをクリックしたときにTreeViewで内部ノードから読み込みを行いたい場合などに役立ちます。最後の行では、デバッグ用として、現在のコンテキストキーをページ上のラベルに表示します。
TreeView1_OnSelectedNodeChanged関数は次のとおりです。protected void TreeView1_OnSelectedNodeChanged(object sender, EventArgs e) { // DFB: Get Location of Node Selected used by TreeView // to find a node _currentTreePath = TreeView1.SelectedNode.ValuePath; //lblDescription.Text = "<b>Selected ValuePath :</b>" //+ _currentTreePath ; // DFB: Get Location of web Directory SlideShowExtender1.ContextKey = TreeView1.SelectedNode.Value; //LabelTreeSelectedNode.Text = "<b>SlideShowExtender1.ContextKey: //</b> " + SlideShowExtender1.ContextKey + // "<br><b>Server.MapPath(ContextKey)</b>:" //+ Server.MapPath(SlideShowExtender1.ContextKey); // DFB: If Path is not empty, add it to state so we have it //on postback if (!String.IsNullOrEmpty(_currentTreePath)) { ViewState.Add(_currentTreePath, _currentTreePath); LabelClickthroughURL.Text = "<a href='mailto:?subject=Picture SlideShow from theBerrys&Body=" + HttpContext.Current.Request.Url + "?" + _currentTreePathQueryStringName + "=" + Server.UrlEncode(_currentTreePath) + "'>Send link to this page by email</a><br>"; } }
この関数の最初の2行では、ValuePathを取得してページ上のラベルに設定します。次の数行では、ディレクトリのValueを取得します。この値がSlide Serviceの新しいcontextKeyとなるので、これをページ上のラベルに設定します。次のコードブロックでは、選択されているValuePathをViewStateに追加し、そのValuePathを使用してリンクを作成します。このリンクを他のユーザーに送信すると、ユーザーがリンクをクリックしたときに、この現在のノードを表示している状態のSlideShowに戻ることができます。
default.aspxとdefault.aspx.csへの記述が終わったら、Web.Configに作業用Webサービスと有効な値が設定されていることを確認します。
まとめ
まずスライドショーサービスをビルドして、このサービスが有効な情報を返すことを確認します。関数シグネチャは厳密であるため、文字や大文字と小文字を変更しないでください。次に、ナビゲーション用のTreeViewと表示用のAJAX SlideShowを追加して、default.aspxと分離コードページをビルドします。著者紹介
Dina Fleet Berry(Dina Fleet Berry)
New Topics
Special Ad
| “超高速無線 LAN 時代”の幕開け--新規格 11ac(Draft)に対応したバッファロー最新ルーターの潜在能力を試す | |
![]() |
バッファローは次世代無線 LAN 規格 IEEE802.11ac(Draft)通信速度最大 1,300Mbps 対応無線 LAN ルーター「WZR-1750DHP」を3月下旬に販売開始。今回、同機器を入手できたので、使用感や便利な機能についてレポートしたい。⇒詳細記事へ |
Hot Topics
IT Job
今週のIT求人情報
Interviews / Specials
Follow japan.internet.com
Popular
Access Ranking
Partner Sites
GetNoImagesFoundDirectory - NoImagesFoundLocation found 









