ScottGu's blog translated by Chica @ Wankuma

asp:ListView コントロール(パート 1 - クリーンなCSS UIを使用してProductリストページを構築)

  

ASP.NET3.5の新しいコントロールの1つで非常に人気のあるものは<asp:ListView>コントロールだと思います。ListView コントロールは、GridViewの様なハイレベルなコントロールのデータの編集、挿入、削除、ページング、ソートのセマンティックスをサポートしています。しかし、GridViewとは違い、生成されたHTMLマークアップを完全に制御することが可能です。

ListViewコントロールは、VS 2008 Web デザイナと CSSサポートと組み合わせたとき、よりクリーンなHTML UIを構築することができます。今後数週間に渡り、いくつかのブログ投稿をまとめて、使用方法をご覧頂こうと思います。

製品カタログページの構築

本日のブログ投稿では、簡単なところから始めて、以下のような基本的な製品カタログリストページを構築しようと思います。

このproducts.aspxページはURLのCatalogインデックスを取って、LINQ to SQLを使用して製品情報を取得・表示します。製品リストの下でページング操作もできるようにしています。(そして、データベースで全てのページング操作を行います。そうすることで、1度に6つの製品のみをデータベースから取得します。)

サーバからのHTMLマークアップ出力は100%CSSベースになります。(表もインラインスタイルもありません。)

ステップ 1: ネスト化されたマスターページでサイトのレイアウトを定義

製品ページにとりかかる前に、まずサイトのすべてのUIとレイアウト構造を定義したいと思います。

もし"デザインの苦手"なタイプだったとしたら、新しいサイトをつくる1つの方法として、無料のHTMLサイトテンプレートを使用します。これらは次の2つのサイトからダウンロードできます。http://www.opensourcetemplates.org/ または http://www.oswd.org/ これらのサイトのテンプレートは純粋なHTML(つまり、サーバサイドプログラミング技術を使ってそれらを使うことができるということです。)で、クリーンなCSSとXHTMLマークアップを使って構築します。このブログ投稿では、ここの"TerraFirma"テンプレートを使用することにしました。

テンプレートをダウンロードした後で、最初にしたことはルートの"Site.Master"マスターページを作成してサイトの全体のレイアウト構造を定義しました。その後、いくつかのネスト化されたマスターページを作成して、様々なカラムスタイルのレイアウトを定義しました。("SingleColumn.master(1列用)"や"TwoColumn.master(2列用)")VS2008はネスト化されたマスターページの作成と使用を大いにサポートしているので、これを簡単に行うことができます。これらの定義・使用方法は以前のVS 2008 ネスト化されたマスターページブログ投稿をお読みください。

一度マスターページのレイアウトを作成すると、1列のネスト化されたマスターページをベースにしたサイトに新しい製品カタログページを作成することができます。(フルスクリーン画像は以下をクリックしてください。)

上記をご覧頂ければ、どのようにして新しいVS2008の縦割りビューモード機能を使用することができるかをご確認頂けると思います。上記では、"縦割りビュー"オプションを使用しているので、ソースとデザインビューの両方をワイドスクリーンモニターで見ることができます。これを有効にする方法は、VS 2008で縦割りビューが可能にブログ投稿でご確認いただけます。

ステップ 2: モックHTML UIを使用してCSSルールを定義

ページの製品UIを定義することに関しては、使用できる方法が2つほどあります。1つはいくつかのDynamic Data UIを生成するコードを書くことから始めて、その後に美しく見せるように仕上げます。もう1つの方法は、まずHTML UIを作ってみて、その後それが気に入り次第、動的になるようにコードを書いていきます。このブログ投稿では2つ目の方法をとります。

まずは ページへ製品コンテンツの標準の<ul><li> リストを追加していきます。

上記でご覧頂けるように、この<ul>リストは非常に見た目が悪く、明らかにこのような製品リストページは作りたくないです。もっと魅力的にするために、VS 2008 Web デザイナと CSSサポートブログ投稿でカバーした新しいCSS編集機能をいくつか使います。

特にVS2008にある新しい"管理スタイル"ツールウィンドウを開いてみようと思います。(これはフォーマット-CSSスタイル-管理スタイルのメニュー項目を選択して開きます。)

管理スタイルウィンドウで簡単に現在CSSスタイルシートにあるすべてのCSSルールを見ることができます。またCSSセレクタの値を簡単に検索し、CSSルールをスタイルシートでリファクタリングでき、新しいルールを作成することができます。

"管理スタイル"ウィンドウの"新しいスタイル..."リンクを選択することで製品リストに新しいCSSルールを作成することができます。これによりダイアログが表示されるので、CSSルールの定義する場所を選択し、そこに対して設定を構成することができます。このサンプルでは、CSSセレクタを".productslist li"と名づけ、"既存のスタイルシートに定義"オプションを選択してアプリケーションで既にある外部のスタイルシートに追加します。

"OK"をクリックして、ソースモードに戻り、<ul>リスト上でCSSルールを割り当てます。(ソースビューでVS2008が現在どのようにCSSインテリセンスを提供しているかをご確認ください。)

現在CSSルールにはそれに割り当てている設定がありませんので、<ul>リストは前のものとまだ同じです。CSS設定をいくつか割り当てることで変更することができます。

CSS設定を行う方法が3つほどあります。1)CSSスタイルシートを開いてソースモードでそれらを設定する。2)設定するために前に確認した管理スタイルダイアログを使用する。3)新しいCSSプロパティウィンドウを使用してCSSルールをリアルタイムでデザイナで編集する。「ビュー>CSSプロパティメニュー」でCSSプロパティウィンドウを開くことができます。

ソースビューでもデザインビューでも要素を選択した時、CSSプロパティウィンドウはそこへ適用するCSSルールをすべてリストアップします。CSSプロパティウィンドウの一番上にある"適用されたルール"は、カスケーディングルールの優先順位を示しています。下のCSSプロパティリストは全ての要素に割り当てられた設定値を表しています。

スタイルアプリケーションのツールバーにある"ターゲットのルール"ドロップダウンは、CSSプロパティウィンドウでどのCSSセレクタの変更が割り当てられるかが表示されます。上記の例では、.productlist liルールは現在選択しているCSSセレクタです。つまりCSSプロパティウィンドウで値を設定すると、外部のCSSスタイルシートでそのルール名の配下で保存されます。スタイル設定はHTMLページのインラインでは保存されません。

".productlist li"CSSルールにいくつか変更を加えてみましょう。まずレイアウト表示モードを"inline"に変更します。:

そして各<li>を左にフロートします。

最後に各<li>要素の下と左のマージンに15px設定して製品間にうまくスペースを入れます。

これが行われた時にHTMLページにはインラインスタイルは保存されないことに注意してください。

その代わり、全て外部CSSスタイルシートの"productlist li"CSSセレクタの配下にクリーンに保存されています。

あと残っていることは、いくつか静的なHTMLをデータベースからの動的なデータと入れ替えることです。

ステップ 3: LINQ to SQLデータモデルを定義

LINQ to SQLを使用して製品データをデータベースから取得します。LINQ to SQLは.NET3.5でビルドされた新しいORM(オブジェクトリレーショナルマッパー)実装です。詳細については現在進行中のLINQ to SQLブログシリーズでご確認いただけます。(近くまた投稿します。)

製品データにNorthwindサンプルデータベースを使用し、以下のようにデータモデルクラスをLINQ to SQL ORMデザイナで定義します。

LINQ to SQLデータモデルを一度定義すると、<asp:listview>コントロールを使用してデータをそれにバンドすることができます。

ステップ 4: <asp:ListView>コントロールを使用してHTMLモックUIを変換

<asp:listview>コントロールはテンプレート駆動コントロールです。コントロール自身は"ビルドイン"のUI、また実際のHTMLマークアップを出力しません。代わりに以下のテンプレートを使用して表示したい好きなマークアップを定義することができます。

  • レイアウトテンプレート
  • 項目テンプレート
  • 1つ置きの項目テンプレート
  • 選択項目テンプレート
  • 編集項目テンプレート
  • 挿入項目テンプレート
  • 空 項目テンプレート
  • 空 データテンプレート
  • 項目セパレータテンプレート
  • グループテンプレート
  • グループセパレータテンプレート

上記のリストにある最初の2つのテンプレートは、レイアウトテンプレートと項目テンプレートで、最終的に利用することになるような非常に一般的なものです。<LayoutTemplate>テンプレートは、データUIの外側のコンテナ・ラッパーを定義することができます。<ItemTemplate>テンプレートは、リストの各項目を定義することができます。

<LayoutTemplate>内では、"項目コンテナ"コントロールを定義して、出力マークアップに<ItemTemplate>項目を動的に追加するために<asp:ListView>コントロールをどこに配置したいかを示します。

これがどのように動作するか確認するために、モック製品HTML UIを見てみます。

<asp:listview>と入れ替えて、動的に全く同じマークアップの出力を生成します。

上記をご覧頂いて、リスト内のどこに項目を追加したいかを示すために、どのように<asp:placeholder>コントロールを<LayoutTemplate>内で使用しているかご確認ください。必要なら、itemContainerとして他のコントロールを代わりに使用することができますが、itemContainerとして<asp:placehoder>コントロールを使用することによって他のID値や余分なマークアップの生成を防ぐことができます。

また上記でどのように<EmptyDataTemplate>を定義しているかもご確認ください。もし一連の空のデータをListViewに割り当てたとしたら、これが<LayoutTemplate>の代わりに表示されます。これは製品がカタログになかった時のイベントで不注意に空の<ul></ul>要素が表示されないようにします。

上記で一度テンプレートを定義すると、LINQ to SQLを使用して製品データを取得しListViewにバインドするコードをコードビハインドファイルに書くことができます。

VB:

C#:

これでページを起動して、有効なカテゴリIDをクエリストリング引数として提供すると、動的にデータベースから製品が引き出されるのを見ることができます。

製品のないカテゴリを試してみると、空のテンプレートメッセージが表示されます。

もしブラウザの製品ページ上で"ソースの表示"をすると、ListViewコントロールから生成されたマークアップが静的なHTMLと同じであることが分かります。

生成されたID要素またはインラインスタイルはありません。全ての生成されたHTML要素や属性を完全に制御することができます。

ステップ 5: コードを書く代わりに<asp:LinqDataSource>コントロールを使用

上記の前のステップで、<asp:ListView>とデータバインドする手続き上のLINQ to SQLコードを書きました。明らかにこれは動作し、実行されたロジックに対してかなりの制御が可能です。

代替えで使用できるその他のオプションは宣言型のASP.NETデータソースコントロールです。すべてのASP.NET 2.0のデータソースコントロール(SqlDataSource、ObjectDataSource、AccessDataSource、XmlDataSource、SiteMapDataSourceなど)は、ListViewと動作します。また新しい<asp:LinqDataSource>コントロールも使用することができます。LinqDataSourceの詳細は、以前のパート5: ASP:LinqDataSourceコントロールを使用してUIをバインディングブログ投稿をご覧ください。

<asp:LinqDataSource> を上記サンプルで使用するには、まず前回コードビハインドファイルに書いたコードを削除し、デザイナ上の<asp.ListView>コントロールをクリックし、"データソースを選択-新しいデータソース"オプションを選択します。"LINQ データソース"オプションをデータソースダイアログから選択し、前に作成したNorthwindデータモデルへバインドします。

Northwindデータモデルの"Products"エンティティコレクションに対してListViewのバインドを選択します。

そして"Where"ボタンをクリックして、クエリストリングの"category"値に基づいてLINQフィルタを構成します。(またフォーム値、クッキー、セッション値、その他のコントロールなどから値をバインドすることもできます。)

"OK"ボタンをクリックすると、ListViewのDataSourceIDがページ内の新しい<asp:LinqDataSource>に設定されます。

そしてアプリケーションにコードを一切持つことなく、LINQ to SQLデータモデルに対してカスタムHTML UIがデータバインドされて製品リストが表示されます。

ステップ 6: <asp:DataPager>コントロールを使用してサーバサイドページングを有効化

このサンプルの最後のステップは製品データに対してページングのサポートを有効化することです。例えば、ページ上に1度に6製品だけ表示させ、ユーザが製品群を前後に操作できるような便利なページ番号UIを提供したいことがあります。

ASP.NET 3.5で新しいコントロールの1つに<asp:DataPager>コントロールがあります。これはListViewコントロールとのデータのページングシナリオを非常に簡単にします。ページ上のどこかにドロップし、"PagedControlID"プロパティにListViewをポイントする設定をし、その"PageSize"プロパティでListViewに一度に表示したい項目数を設定します。

そうすると<asp:DataPager>はListViewに対してナビゲーションUIを出力します。

そしてもし上記のページングUIで"2"のリンクをクリックした場合、同カテゴリの残りの5つの製品を表示します。

<asp:LinqDataSource>は自動的にサーバサイドのデータページングに対するLINQ to SQLのビルドインサポートを使用して、必ず一度に6つの製品(PageSizeが6の場合)だけがデータベースから取得されるようにします。つまり、たとえ1つのカテゴリに何千もの製品があった場合でもアプリケーションとデータベースが調整します。

ディスクレーマ: ベータ2の<asp:DataPager>には確かにいくつか制限があり、デフォルトでクエリストリング値を取り払うことができません。それによりあまり検索エンジンフレンドリーでない状態になります。今後のブログ投稿でこの修正とクエリストリングのインデックスをサポートの方法をカバーしたいと思います。

まとめ

上記のチュートリアルで新しい<asp:ListView>コントロールを使用する第一歩を上手くまとめられていればと思います。このコントロールによりクライアントに送られるマークアップの出力に対して完全な制御を行うことができます。(リッチデータのページング、編集、削除、挿入のセマンティックスを提供したままの状態で。)今後のブログ投稿でこれらのシナリオ(ListViewのかっこいいグループ化機能と一緒に)をもっとたくさんカバーしていきます。

上記のサンプルをダウンロードして自分のマシンでお試し頂く場合はここをクリックしてください。

Hope this helps - and have a great weekend!

Scott

ScottGu's blog translated by Chica @ Wankuma 

※本翻訳に関しまして、Scottさんにはご了承頂いております。