|
ASP.NET 3.5の新しいListViewコントロールを使用するはじめにユーザー中心のアプリケーションを作成するためには、ある種のデータ統合が必要です。少なくとも、リレーショナルデータベースやXMLファイルなどのデータソースからデータを取得した場合は、その書式を整えてから、ユーザーインターフェイスに表示する必要があります。以前のバージョンのASP.NETにも、GridViewなど、データ中心の表示コントロールは存在していました。しかし、これらのコントロールは、プロのWeb開発者にとって不可欠なカスタマイズと拡張性の機能に欠けていました。 この欠点を解決するために、ASP.NET 3.5では、カスタマイズと拡張性の機能に優れているListViewという新しいコントロールが導入されました。これらの機能を使用すると、テンプレートとスタイルを利用してどのような形式のデータでも表示でき、最小限のコードでCRUD(作成、読み取り、更新、削除)操作も実行できます。 この記事では、新しいListViewコントロールを使用する場合のデータアクセスの手順について詳しく説明します。また、データの編集やイベントの処理など、高度な機能についても説明します。 ListViewコントロールの基礎ASP.NETで提供されるほとんどのデータバインドコントロールは、表示されるデータを追加のマークアップで自動的に囲みます。たとえば、GridViewコントロールはレンダリングされるデータをHTMLテーブル(<table>)内に表示しますが、このとき、バインドされるデータの各レコードはテーブル行(<tr>)として表示され、各レコードフィールドは行内のセル(<td>)として表示されます。TemplateField要素や他のツールを使用してGridViewの外観をカスタマイズすることはできますが、GridViewの出力は依然としてtable要素内にあります。しかし、データバインドコントロールによって生成される外観のHTMLマークアップを、完全に制御したいこともあります。ListViewコントロールは、まさにこのために導入されました。 ListViewコントロールの場合、レンダリングされる出力が追加のマークアップで自動的に囲まれることはありません。ListViewコントロールでは、レンダリングされる的確なHTMLを指定するのはあくまでもそれを使用する開発者です。 的確なマークアップを指定するには、ListViewのビルトインテンプレートを使用します。表1に、ListViewコントロールがサポートするテンプレートを示します。 表1 ListViewコントロールがサポートするテンプレート
たとえば次のコードは、ListView内のHTML tableコントロールに指定されている項目のリストを表示します。
<asp:ListView ID="..." runat="server" DataSourceID="...">
<LayoutTemplate>
<table .......>
<tr runat="server" ID="itemPlaceholder"></tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%# Eval("Name") %></td>
</tr>
</ItemTemplate>
</asp:ListView>
単純なデータバインディングの例ListViewコントロールがサポートするさまざまなテンプレートについて理解したところで、次に、新しいサンプルWebサイトを作ってみましょう。このサンプルには「ListViewExample」という名前を付けます(ソースコードは本稿冒頭のリンクからダウンロードできます)。Webサイトを作成したら、メニューから[Website]→[Add New Item]を選択し、「SimpleListView.aspx」という名前の新しいASP.NETページを追加します(リスト1を参照)。このページでは、ListViewコントロールを使用して、AdventureWorksサンプルデータベース内のProductテーブルから製品データを表示します。 リスト1 SimpleListViewページ
<%@ Page Language="C#" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<link rel="Stylesheet" type="text/css" href="StyleSheet.css" />
<title>Simple Data Binding Example using ListView control</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ListView runat="server" ID="productsView"
DataSourceID="productSource" DataKeyNames="ProductID">
<LayoutTemplate>
<table cellpadding="2" runat="server" id="tblProducts"
style="width:460px">
<tr runat="server" id="itemPlaceholder">
</tr>
</table>
<asp:DataPager runat="server" ID="DataPager" PageSize="3">
<Fields>
<asp:NumericPagerField ButtonCount="10"
PreviousPageText="<--" NextPageText="-->" />
</Fields>
</asp:DataPager>
</LayoutTemplate>
<ItemTemplate>
<tr id="row" style="height:72px" runat="server">
<td valign="top" class="ProductInfo">
Product ID : <asp:Label ID="lblProductID" runat="server"
Text='<%#Eval("ProductID") %>' />
<br />
Name : <asp:Label ID="lblName" runat="server"
Text='<%#Eval("Name") %>' />
<br />
Product Number : <asp:Label ID="lblProductNumber"
runat="server" Text='<%#Eval("ProductNumber") %>' />
</td>
</tr>
</ItemTemplate>
<ItemSeparatorTemplate>
<tr id="separator" style="height:10px" runat="server">
<td>--------------------------------------------------------
------------------</td>
</tr>
</ItemSeparatorTemplate>
<EmptyDataTemplate>
There are no products!
</EmptyDataTemplate>
</asp:ListView>
<asp:SqlDataSource id="productSource" runat="server"
DataSourceMode="DataSet"
ConnectionString="<%$ ConnectionStrings:AdventureWorks%>"
SelectCommand="SELECT ProductID,Name,ProductNumber,
Color,ListPrice FROM Production.Product">
</asp:SqlDataSource>
</div>
</form>
</body>
</html>
ConnectionStringプロパティとSelectCommandプロパティを適切な値に設定することにより、AdventureWorksデータベースのProductテーブルからデータを取得します。ConnectionStringプロパティは、ASP.NET式を通じて「web.config」ファイルから接続文字列を取得します。筆者のテストマシンでは、接続文字列は「web.config」内で次のように定義されています。
<connectionStrings>
<add name="AdventureWorks"
connectionString="server=localhost;uid=sa;
pwd=thiru;database=AdventureWorks;"/>
</connectionStrings>
<LayoutTemplate>
<table cellpadding="2" runat="server" id="tblProducts"
style="width:460px">
<tr runat="server" id="itemPlaceholder">
</tr>
</table>
<asp:DataPager runat="server" ID="DataPager" PageSize="3">
<Fields>
<asp:NumericPagerField ButtonCount="10"
PreviousPageText="<--" NextPageText="-->" />
</Fields>
</asp:DataPager>
</LayoutTemplate>
DataPagerコントロールとデータバインドコントロールを関連付けるには、次の2つの方法があります。
PageSizeプロパティを設定することで、各データページに表示される項目数を制御できます。QueryStringFieldプロパティを設定して、ページをサーバーに送信する方法を変更することもできます。DataPagerコントロール内でNumericPageFieldテンプレートを指定すると、ユーザーは、ページ番号を選択することによって特定のページに移動できます。
<asp:NumericPagerField ButtonCount="10"
PreviousPageText="<--"
NextPageText="-->" />
Eval()文を通じてデータソースコントロールからデータを取得することにより、各レコードの詳細にマークアップを適用します。図1は、ブラウザ内でページに移動したときに生成される出力を示しています。 図1 単純なListView。Productデータを取得するSqlDataSourceコントロールにListViewコントロールをデータバインドすることによって生成される出力
![]() ListViewコントロールでのデータの編集これまでの説明でお分かりのように、ListViewコントロールを使用してデータを表示することは比較的簡単です。さらに、ListView内のデータをユーザーに編集させることも可能です。サンプルWebサイトに「ListViewEditExample.aspx」という名前の新しいASP.NETページを追加し、そのコードをリスト2のように変更します。リスト2 編集可能なListView
<%@ Page Language="C#" %>
<script runat="server">
void deptsView_ItemUpdated(object sender,
ListViewUpdatedEventArgs e)
{
lblResult.Text = e.AffectedRows.ToString() +
" row(s) successfully updated";
}
void deptsView_PagePropertiesChanged(object sender, EventArgs e)
{
//Set the text to empty when navigating to a different page
lblResult.Text = "";
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<link rel="Stylesheet" type="text/css" href="StyleSheet.css" />
<title>Editing Data using ListView Control</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ListView ID="ContactsListView" DataSourceID="deptSource"
DataKeyNames="DepartmentID" runat="server"
OnItemUpdated="deptsView_ItemUpdated"
OnPagePropertiesChanged="deptsView_PagePropertiesChanged">
<LayoutTemplate>
<table cellpadding="2" width="640px" border="1"
runat="server" id="tblProducts">
<tr id="row1" runat="server" class="header">
<th id="header2" runat="server">Name</th>
<th id="header3" runat="server">Group Name</th>
<th id="header1" runat="server">Action</th>
</tr>
<tr runat="server" id="itemPlaceholder" />
</table>
<asp:DataPager runat="server" ID="deptsDataPager"
PageSize="3">
<Fields>
<asp:NextPreviousPagerField ShowFirstPageButton="True"
ShowLastPageButton="True" FirstPageText="|<< "
LastPageText=" >>|" NextPageText=" > "
PreviousPageText=" < " />
</Fields>
</asp:DataPager>
</LayoutTemplate>
<ItemTemplate>
<tr id="row2" runat="server">
<td>
<asp:Label ID="lblName" runat="Server"
Text='<%#Eval("Name") %>' />
</td>
<td valign="top">
<asp:Label ID="lblGroupName" runat="Server"
Text='<%#Eval("GroupName") %>' />
</td>
<td>
<asp:LinkButton ID="btnEdit" runat="Server" Text="Edit"
CommandName="Edit" />
</td>
</tr>
</ItemTemplate>
<EditItemTemplate>
<tr style="background-color: #ADD8E6">
<td>
<asp:TextBox ID="txtName" runat="server"
Text='<%# Bind("Name") %>'
MaxLength="50" /><br />
</td>
<td>
<asp:TextBox ID="txtGroupName" runat="server" Text='<%#
Bind("GroupName") %>' MaxLength="50" /><br />
</td>
<td>
<asp:LinkButton ID="btnUpdate" runat="server"
CommandName="Update" Text="Update" />
<asp:LinkButton ID="btnCancel" runat="server"
CommandName="Cancel" Text="Cancel" />
</td>
</tr>
</EditItemTemplate>
</asp:ListView>
<asp:SqlDataSource ID="deptSource" runat="server"
ConnectionString="<%$ ConnectionStrings:AdventureWorks %>"
SelectCommand="SELECT [DepartmentID],[Name],[GroupName] FROM
HumanResources.Department" UpdateCommand="UPDATE
HumanResources.Department SET Name = @Name,
GroupName = @GroupName WHERE DepartmentID = @DepartmentID">
</asp:SqlDataSource>
<br /><br />
<asp:Label runat="server" ID="lblResult" Text=""
Font-Bold="true" />
</div>
</form>
</body>
</html>
最初に、SqlDataSourceコントロールの UpdateCommandプロパティに、実行するSQL文を指定します。このSQL文が実行されると、ユーザー指定の最新の値でデータベースが更新されます。
<asp:SqlDataSource ID="deptSource" runat="server"
ConnectionString="<%$ ConnectionStrings:AdventureWorks %>"
SelectCommand="SELECT [DepartmentID],[Name],[GroupName] FROM
HumanResources.Department" UpdateCommand="UPDATE
HumanResources.Department SET Name = @Name,
GroupName = @GroupName WHERE DepartmentID = @DepartmentID">
</asp:SqlDataSource>
<ItemTemplate>
----
----
<asp:LinkButton ID="btnEdit" runat="Server" Text="Edit"
CommandName="Edit" />
</td>
</tr>
</ItemTemplate>
<EditItemTemplate>
<tr style="background-color: #ADD8E6">
<td>
<asp:TextBox ID="txtName" runat="server"
Text='<%# Bind("Name") %>'
MaxLength="50" /><br />
</td>
<td>
<asp:TextBox ID="txtGroupName" runat="server" Text='<%#
Bind("GroupName") %>' MaxLength="50" /><br />
</td>
<td>
<asp:LinkButton ID="btnUpdate" runat="server"
CommandName="Update" Text="Update" />
<asp:LinkButton ID="btnCancel" runat="server"
CommandName="Cancel" Text="Cancel" />
</td>
</tr>
</EditItemTemplate>
CommandNameプロパティを目的の値(表2を参照)に設定することにより定義します。表2 LinkButtonのCommandNameプロパティに指定できる値
図2 編集可能なListView。編集可能として設定したListViewコントロールでは、各レコードに対してEditリンクが表示される。このリンクをクリックすると、ListViewコントロールのコンテンツが編集モードに切り替わる
![]() 図3 編集モード。編集モードでは、EditItemTemplate要素によってテキストボックスが生成される。ユーザーはこのテキストボックスに、NameフィールドとGroupNameフィールドの更新後の値を入力できる
![]() 図4 影響を受けたレコード。更新プロセスの終了時に、更新操作の影響を受けたレコード数がLabelコントロールに表示される
![]() 本稿では、この機能を使用した例を2つ紹介しました。1つ目の例では、単純なデータドリブンのWebページを作成しました。2つ目の例では、適切な編集と確認のマークアップを指定して、コントロールの更新機能を宣言的に利用する複雑なページを作成しました。また、ListViewコントロールが生成するイベントの処理方法についても説明しました。 おわかりのように、ListViewの拡張的な特性を利用すると、実行時の動作を各自のニーズに合わせて簡単にカスタマイズできます。 著者紹介Thiru Thangarathinam(Thiru Thangarathinam)
オブジェクト指向アプリケーション開発方法論を用いたアプリケーションのアーキテクチャ設計、設計、開発、および実装に関して約6年の経験を持つ。ソフトウェアライフサイクル(設計、開発およびテスト)にも精通。
ASP.NET、.NET Framework、Visual C#.NET、Visual Basic.NET、ADO.NET、XML Webサービス、および.NET Remotingのエキスパートであり、MCAD(.NETトラック)、MCSD、およびMCP資格を保有。
多くの書籍や記事を執筆。メールの宛先はthiruthangarathinam@yahoo.com。
関連記事 最新トップニュース
|
|