DataList のデータの編集と削除の概要 (C#)
DataList には組み込みの編集および削除機能はありませんが、このチュートリアルでは、基になるデータの編集と削除をサポートする DataList を作成する方法について説明します。
はじめに
データの挿入、更新、および削除の概要に関するチュートリアルでは、アプリケーション アーキテクチャ、ObjectDataSource、GridView、DetailsView、FormView コントロールを使用してデータを挿入、更新、削除する方法について説明しました。 ObjectDataSource とこれら 3 つのデータ Web コントロールでは、単純なデータ変更インターフェイスの実装は簡単であり、スマート タグからチェック ボックスをオンにするだけでした。 コードを記述する必要はありませんでした。
残念ながら、DataList には、GridView コントロールに固有の組み込みの編集機能と削除機能がありません。 この不足している機能の一部は、DataList が宣言型データ ソース コントロールとコードフリーのデータ変更ページが使用できなかった以前のバージョンの ASP.NET のレリックであることが原因です。 ASP.NET 2.0 の DataList には、GridView と同じすぐに使用できるデータ変更機能はありませんが、ASP.NET 1.x の手法を使用してそのような機能を含めることができます。 この方法には少しコードが必要ですが、このチュートリアルで説明するように、DataList には、このプロセスを支援するためにいくつかのイベントとプロパティが用意されています。
このチュートリアルでは、基になるデータの編集と削除をサポートする DataList を作成する方法について説明します。 今後のチュートリアルでは、入力フィールドの検証、データ アクセスまたはビジネス ロジック レイヤーから発生した例外の適切な処理など、より高度な編集と削除のシナリオについて説明します。
Note
DataList と同様に、Repeater コントロールには、挿入、更新、または削除のための既定の機能がありません。 そのような機能を追加することはできますが、DataList には、このような機能の追加を簡略化する Repeater にないプロパティとイベントが含まれています。 したがって、このチュートリアルと今後の編集と削除については、DataList に重点を置きます。
手順 1: チュートリアル Web ページの編集と削除の作成
DataList からデータを更新および削除する方法を調べる前に、まず、このチュートリアルと次のいくつかのページに必要な ASP.NET ページを Web サイト プロジェクトに作成してみましょう。 まず、EditDeleteDataList
という名前の新しいフォルダーを追加します。 次に、次の ASP.NET ページをそのフォルダーに追加し、各ページを Site.master
マスター ページに関連付けます。
Default.aspx
Basics.aspx
BatchUpdate.aspx
ErrorHandling.aspx
UIValidation.aspx
CustomizedUI.aspx
OptimisticConcurrency.aspx
ConfirmationOnDelete.aspx
UserLevelAccess.aspx
図 1: チュートリアルの ASP.NET ページを追加する
他のフォルダーと同様に、EditDeleteDataList
フォルダーの Default.aspx
のセクションにチュートリアルが一覧表示されます。 SectionLevelTutorialListing.ascx
ユーザー コントロールではこの機能が提供されていることを思い出してください。 そのため、このユーザー コントロールをソリューション エクスプローラーからページのデザイン ビューにドラッグして Default.aspx
に追加します。
図 2: SectionLevelTutorialListing.ascx
ユーザー コントロールを Default.aspx
に追加する (クリックするとフルサイズの画像が表示されます)
最後に、このページをエントリとして Web.sitemap
ファイルに追加します。 具体的には、DataList と Repeater <siteMapNode>
を使用してマスター/詳細レポートの後に次のマークアップを追加します。
<siteMapNode
title="Editing and Deleting with the DataList"
description="Samples of Reports that Provide Editing and Deleting Capabilities"
url="~/EditDeleteDataList/Default.aspx" >
<siteMapNode
title="Basics"
description="Examines the basics of editing and deleting with the
DataList control."
url="~/EditDeleteDataList/Basics.aspx" />
<siteMapNode
title="Batch Update"
description="Examines how to update multiple records at once in a
fully-editable DataList."
url="~/EditDeleteDataList/BatchUpdate.aspx" />
<siteMapNode
title="Error Handling"
description="Learn how to gracefully handle exceptions raised during the
data modification workflow."
url="~/EditDeleteDataList/ErrorHandling.aspx" />
<siteMapNode
title="Adding Data Entry Validation"
description="Help prevent data entry errors by providing validation."
url="~/EditDeleteDataList/UIValidation.aspx" />
<siteMapNode
title="Customize the User Interface"
description="Customize the editing user interfaces."
url="~/EditDeleteDataList/CustomizedUI.aspx" />
<siteMapNode
title="Optimistic Concurrency"
description="Learn how to help prevent simultaneous users from
overwritting one another s changes."
url="~/EditDeleteDataList/OptimisticConcurrency.aspx" />
<siteMapNode
title="Confirm On Delete"
description="Prompt a user for confirmation when deleting a record."
url="~/EditDeleteDataList/ConfirmationOnDelete.aspx" />
<siteMapNode
title="Limit Capabilities Based on User"
description="Learn how to limit the data modification functionality
based on the user s role or permissions."
url="~/EditDeleteDataList/UserLevelAccess.aspx" />
</siteMapNode>
Web.sitemap
を更新した後、少し時間を取って、ブラウザーを介してチュートリアル Web サイトを表示します。 左側のメニューに、DataList の編集と削除のチュートリアル用の項目が含まれるようになりました。
図 3: サイト マップに DataList の編集と削除のチュートリアルのエントリが含まれるようになりました
手順 2: データの更新と削除の手法を調べる
GridView と ObjectDataSource が連携して機能するため、GridView を使用したデータの編集と削除は非常に簡単です。 挿入、更新、削除に関連するイベントの検査のチュートリアルで説明したように、行の [更新] ボタンをクリックすると、GridView では、双方向データ バインドを使用したフィールドを ObjectDataSource の UpdateParameters
コレクションに自動的に割り当て、その ObjectDataSource の Update()
メソッドを呼び出します。
残念ながら、DataList には、この組み込み機能はありません。 ユーザーの値が ObjectDataSource のパラメーターに割り当てられ、その Update()
メソッドが呼び出されるようにする必要があります。 この取り組みを支援するために、DataList には次のプロパティとイベントが用意されています。
- 更新時または削除時の
DataKeyField
プロパティは、DataList 内の各項目を一意に識別できる必要があります。 このプロパティを、表示されるデータの主キー フィールドに設定します。 これにより、DataList のDataKeys
コレクションに、DataList 項目ごとに指定したDataKeyField
値が設定されます。 EditCommand
イベントは、CommandName
プロパティが Edit に設定されている Button、LinkButton、または ImageButton がクリックされたときに発生します。CancelCommand
イベントは、CommandName
プロパティが Cancel に設定されている Button、LinkButton、または ImageButton がクリックされたときに発生します。UpdateCommand
イベントは、CommandName
プロパティが Update に設定されている Button、LinkButton、または ImageButton がクリックされたときに発生します。DeleteCommand
イベントは、CommandName
プロパティが Delete に設定されている Button、LinkButton、または ImageButton がクリックされたときに発生します。
これらのプロパティとイベントを使用して、DataList からデータを更新および削除するために使用できる 4 つの方法があります。
- ASP.NET 1.x の手法を使用する。DataList は ASP.NET 2.0 および ObjectDataSources より前に存在し、プログラムによる方法でデータを完全に更新および削除できました。 この手法では ObjectDataSource が完全に削除され、データをビジネス ロジック レイヤーから DataList に直接バインドする必要があります。これは、表示するデータを取得するときと、レコードを更新または削除する場合の両方です。
- ページで単一の ObjectDataSource コントロールを使用して、選択、更新、および削除を行う。DataList には GridView にはある編集および削除機能がありませんが、自分で追加できないわけではありません。 この方法では、GridView の例と同様に ObjectDataSource を使用しますが、ObjectDataSource のパラメーターを設定してその
Update()
メソッドを呼び出す DataList のUpdateCommand
イベントのイベント ハンドラーを作成する必要があります。 - 選択に ObjectDataSource コントロールを使用するが、更新と削除は BLL に対して直接行う。オプション 2 を使用する場合、
UpdateCommand
イベントに少しコードを記述し、パラメーター値を割り当てる必要があります。 代わりに、ObjectDataSource を使用して選択しますが、BLL に対して直接を更新および削除の呼び出しを行います (オプション 1 のように)。 個人的には、BLL と直接やり取りしてデータを更新すると、ObjectDataSource のUpdateParameters
を割り当ててそのUpdate()
メソッドを呼び出すよりも読みやすいコードにつながると思います。 - 複数の ObjectDataSource を通じて宣言的方法を使用する。前の 3 つのアプローチはすべて、少しのコードを必要とします。 できるだけ多くの宣言構文を使用し続ける場合、最後のオプションは、ページに複数の ObjectDataSource を含める方法です。 最初の ObjectDataSource は、BLL からデータを取得し、DataList にバインドします。 更新の場合、別の ObjectDataSource が追加されますが、DataList の
EditItemTemplate
に直接追加されます。 削除のサポートを含めるには、さらに別の ObjectDataSource がItemTemplate
に必要です。 この方法では、これらの埋め込み ObjectDataSource でControlParameters
を使用して、ObjectDataSource のパラメーターをユーザー入力コントロールに宣言的にバインドします (DataList のUpdateCommand
イベント ハンドラーでプログラムで指定するのではなく)。 この方法では、埋め込み ObjectDataSource のUpdate()
またはDelete()
コマンドを呼び出すためのコードが少し必要ですが、他の 3 つの方法よりもはるかに少なくて済みます。 ここでの欠点は、複数の ObjectDataSource がページを乱雑にし、全体的な読みやすさを損なうことです。
これらのアプローチのいずれか 1 つだけを使用することを余儀なくされた場合は、オプション 1 を選択します。これは、最も柔軟性が高く、DataList がもともとこのパターンに対応するように設計されているためです。 DataList は、ASP.NET 2.0 データ ソース コントロールと連携するように拡張されましたが、公式の ASP.NET 2.0 データ Web コントロール (GridView、DetailsView、FormView) のすべての機能を備えているわけではありません。 ただし、オプション 2 から 4 にはメリットがないわけではありません。
このチュートリアルと今後の編集と削除のチュートリアルでは、ObjectDataSource を使用して、表示するデータを取得し、BLL への呼び出しを行ってデータを更新および削除します (オプション 3)。
手順 3: DataList の追加とその ObjectDataSource の構成
このチュートリアルでは、製品情報を一覧表示する DataList を作成し、各製品について、ユーザーが名前と価格を編集し、製品を完全に削除できる機能を提供します。 特に、ObjectDataSource を使用して表示するレコードを取得しますが、BLL と直接やり取りして更新アクションと削除アクションを実行します。 DataList に対する編集と削除機能の実装について心配する前に、まず、読み取り専用インターフェイスで製品を表示するページを取得しましょう。 前のチュートリアルでこれらの手順を調べたので、手早く進めます。
まず、EditDeleteDataList
フォルダー内の Basics.aspx
ページを開き、デザイン ビューから DataList をページに追加します。 次に、DataList のスマート タグから、新しい ObjectDataSource を作成します。 製品データを扱っているため、ProductsBLL
クラスを使用するように構成します。 "すべての" 製品を取得するには、[SELECT] タブで GetProducts()
メソッドを選択します。
図 4: クラスを使用するように ObjectDataSource を構成します ProductsBLL
(フルサイズの画像を表示する をクリックします)
図 5: GetProducts()
メソッドを使用して製品情報を返します (クリックしてフルサイズの画像を表示)
DataList は、GridView と同様に、新しいデータを挿入するために設計されていません。そのため、[INSERT] タブのドロップダウン リストから (なし) オプションを選択します。更新と削除は BLL を介してプログラムによって実行されるため、[UPDATE] と [DELETE] タブにも (なし) を選択します。
図 6: ObjectDataSource の INSERT、UPDATE、DELETE タブのドロップダウン リストが (なし) に設定されていることを確認します (クリックしてフルサイズの画像を表示)
ObjectDataSource を構成したら、[完了] をクリックしてデザイナーに戻ります。 前の例で説明したように、ObjectDataSource 構成を完了すると、Visual Studio によって DropDownList 用の ItemTemplate
が自動的に作成され、各データ フィールドが表示されます。 この ItemTemplate
を、製品名と価格のみを表示する値に置き換えます。 また、RepeatColumns
プロパティを 2 に設定します。
Note
データの挿入、更新、削除の概要のチュートリアルで説明したように、ObjectDataSource を使用してデータを変更する場合、アーキテクチャでは、ObjectDataSource の宣言型マークアップから OldValuesParameterFormatString
プロパティを削除する (または既定値 {0}
にリセットする) 必要があります。 ただし、このチュートリアルでは、データの取得にのみ ObjectDataSource を使用します。 したがって、ObjectDataSource の OldValuesParameterFormatString
プロパティ値を変更する必要はありません (ただし、変更しても問題ありません)。
既定の DataList ItemTemplate
をカスタマイズされたものに置き換えた後、ページの宣言型マークアップは次のようになります。
<asp:DataList ID="DataList1" runat="server" DataKeyField="ProductID"
DataSourceID="ObjectDataSource1" RepeatColumns="2">
<ItemTemplate>
<h5>
<asp:Label runat="server" ID="ProductNameLabel"
Text='<%# Eval("ProductName") %>'></asp:Label>
</h5>
Price: <asp:Label runat="server" ID="Label1"
Text='<%# Eval("UnitPrice", "{0:C}") %>' />
<br />
<br />
</ItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="GetProducts" TypeName="ProductsBLL"
OldValuesParameterFormatString="original_{0}">
</asp:ObjectDataSource>
ブラウザーを使用して進行状況を確認します。 図 7 に示すように、DataList には、各製品の製品名と単価が 2 つの列に表示されます。
図 7: 製品名と価格が 2 列の DataList に表示されます (クリックしてフルサイズの画像を表示)
Note
DataList には、更新と削除のプロセスに必要なプロパティが多数あり、これらの値はビュー状態に格納されます。 そのため、データの編集または削除をサポートする DataList を構築する場合は、DataList のビュー状態を有効にすることが不可欠です。
編集可能な GridView、DetailsViews、FormView を作成するときに、ビュー状態を無効にできたことを、鋭い読者は思い出すかもしれません。 これは、ASP.NET 2.0 Web コントロールに "コントロールの状態" が含まれる可能性があるためです。これは、ビュー状態などのポストバック間で状態が保持されますが、必須と見なされるものです。
GridView でビュー状態を無効にすると、単純な状態情報が省略されるだけで、コントロールの状態 (編集と削除に必要な状態が含まれます) が維持されます。 DataList は、ASP.NET 1.x の時期に作成されており、コントロールの状態を利用しないため、ビュー状態を有効にする必要があります。 コントロールの状態とビュー状態の比較に関するページで、コントロールの状態の目的とビュー状態との違いについて詳しく確認してください。
手順 4: 編集ユーザー インターフェイスを追加する
GridView コントロールは、フィールドのコレクション (BoundFields、CheckBoxFields、TemplateFields など) で構成されます。 これらのフィールドは、モードに応じてレンダリングされるマークアップを調整できます。 たとえば、読み取り専用モードの場合、BoundField はデータ フィールドの値をテキストとして表示します。編集モードでは、Text
プロパティにデータ フィールド値が割り当てられている TextBox Web コントロールがレンダリングされます。
一方、DataList はテンプレートを使用してその項目をレンダリングします。 読み取り専用の項目は ItemTemplate
使用してレンダリングされ、編集モードの項目は EditItemTemplate
を介してレンダリングされます。 この時点で、DataList には ItemTemplate
のみがあります。 項目レベルの編集機能をサポートするには、編集可能な項目に表示するマークアップを含む EditItemTemplate
を追加する必要があります。 このチュートリアルでは、製品名と単価を編集するために TextBox Web コントロールを使用します。
EditItemTemplate
は、宣言型またはデザイナーを使用して作成できます (DataList のスマート タグから [テンプレートの編集] オプションを選択します)。 [テンプレートの編集] オプションを使用するには、まずスマート タグの [テンプレートの編集] リンクをクリックし、ドロップダウン リストから EditItemTemplate
項目を選択します。
図 8: DataList の EditItemTemplate
の使用を選びます (クリックしてフルサイズの画像を表示する)
次に、「Product name:」と「Price:」に入力し、ツールボックスからデザイナーの EditItemTemplate
インターフェイスに 2 つの TextBox コントロールをドラッグします。 TextBox の ID
プロパティを ProductName
と UnitPrice
に設定します。
図 9: 製品名と価格の TexBox を追加します (クリックしてフルサイズの画像を表示)
対応する製品データ フィールドの値を 2 つの TextBox の Text
プロパティにバインドする必要があります。 図 10 に示すように、TextBox スマート タグから [DataBindings の編集] リンクをクリックし、適切なデータ フィールドを Text
プロパティに関連付けます。
Note
UnitPrice
データ フィールドを価格 TextBox の Text
フィールドにバインドする場合は、書式設定を通貨値 ({0:C}
)、一般数値 ({0:N}
)、またはなしにできます。
図 10: TextBox の Text
プロパティに ProductName
と UnitPrice
データ フィールドをバインドする
図 10 の [DataBindings の編集] ダイアログ ボックスには、GridView または DetailsView の TemplateField または FormView のテンプレートを編集するときに表示される双方向データ バインド のチェック ボックスが含まれて "いない" ことに注意してください。 双方向データ バインド機能を使用すると、入力 Web コントロールに入力された値を、対応する ObjectDataSource の InsertParameters
または UpdateParameters
に自動的に割り当てたり、データを挿入または更新したりすることができました。 このチュートリアルの後半で説明するように、DataList は双方向データ バインドをサポートしていません。ユーザーが変更を行い、データを更新する準備ができたら、これらの TextBox の Text
プロパティにプログラムでアクセスし、その値を ProductsBLL
クラスの適切な UpdateProduct
メソッドに渡す必要があります。
最後に、[更新] ボタンと [キャンセル] ボタンを EditItemTemplate
に追加する必要があります。 マスター レコードの箇条書きと詳細 DataList を使用してマスター/詳細を表示するチュートリアルで説明したように、CommandName
プロパティが設定されている Button、LinkButton、または ImageButton が Repeater または DataList 内からクリックされると、Repeater または DataList の ItemCommand
イベントが発生します。 DataList の場合、CommandName
プロパティが特定の値に設定されている場合は、追加のイベントも発生する可能性があります。 特別な CommandName
プロパティ値には、次のようなものがあります。
- Cancel によって
CancelCommand
イベントが発生する - Edit によって
EditCommand
イベントが発生する - Update によって
UpdateCommand
イベントが発生する
これらのイベントは、ItemCommand
イベントに "加えて" 発生することに注意してください。
EditItemTemplate
に 2 つの Button Web コントロールに追加します。1 つの CommandName
は [Update] に設定され、もう 1 つは [Cancel] に設定されています。 これら 2 つの Button Web コントロールを追加すると、デザイナーは次のようになります。
図 11: EditItemTemplate
に更新ボタンとキャンセル ボタンを追加します (クリックしてフルサイズの画像を表示)
EditItemTemplate
が完了すると、DataList の宣言型マークアップは次のようになります。
<asp:DataList ID="DataList1" runat="server" DataKeyField="ProductID"
DataSourceID="ObjectDataSource1" RepeatColumns="2">
<ItemTemplate>
<h5>
<asp:Label runat="server" ID="ProductNameLabel"
Text='<%# Eval("ProductName") %>' />
</h5>
Price: <asp:Label runat="server" ID="Label1"
Text='<%# Eval("UnitPrice", "{0:C}") %>' />
<br />
<br />
</ItemTemplate>
<EditItemTemplate>
Product name:
<asp:TextBox ID="ProductName" runat="server"
Text='<%# Eval("ProductName") %>' /><br />
Price:
<asp:TextBox ID="UnitPrice" runat="server"
Text='<%# Eval("UnitPrice", "{0:C}") %>' /><br />
<br />
<asp:Button ID="UpdateProduct" runat="server"
CommandName="Update" Text="Update" />
<asp:Button ID="CancelUpdate" runat="server"
CommandName="Cancel" Text="Cancel" />
</EditItemTemplate>
</asp:DataList>
手順 5: 編集モードに入る仕組みを追加する
この時点で、DataList には EditItemTemplate
によって編集インターフェイスが定義されています。ただし、現在、ユーザーが製品の情報を編集することを示す方法はありません。 クリックすると、その DataList 項目が編集モードでレンダリングされる各製品に [編集] ボタンを追加する必要があります。 まず、デザイナーまたは宣言によって ItemTemplate
に [編集] ボタンを追加します。 [編集] ボタンの CommandName
プロパティを [Edit] に設定してください。
この [編集] ボタンを追加したら、少し時間を取ってブラウザーでページを表示します。 この追加により、各製品登録情報に [編集] ボタンが含まれているはずです。
図 12: EditItemTemplate
に [更新] ボタンと [キャンセル] ボタンを追加する (クリックしてフルサイズの画像を表示)
ボタンをクリックするとポストバックが発生しますが、製品登録情報は編集モードに "なりません"。 製品を編集可能にするには、次の作業を行う必要があります。
- DataList の
EditItemIndex
プロパティを、[編集] ボタンをクリックされたDataListItem
のインデックスに設定します。 - データを DataList に再バインドします。 DataList が再レンダリングされると、DataList の
EditItemIndex
に対応するItemIndex
を持つDataListItem
で、そのEditItemTemplate
を使用してレンダリングされます。
[編集] ボタンをクリックすると DataList の EditCommand
イベントが発生するため、次のコードを使用して EditCommand
イベント ハンドラーを作成します。
protected void DataList1_EditCommand(object source, DataListCommandEventArgs e)
{
// Set the DataList's EditItemIndex property to the
// index of the DataListItem that was clicked
DataList1.EditItemIndex = e.Item.ItemIndex;
// Rebind the data to the DataList
DataList1.DataBind();
}
EditCommand
イベント ハンドラーは、2 番目の入力パラメーターとして型 DataListCommandEventArgs
のオブジェクトで渡されます。これには、編集ボタンがクリックされた DataListItem
への参照が含まれます (e.Item
)。 イベント ハンドラーでは、最初に DataList の EditItemIndex
を編集可能な DataListItem
オブジェクトの ItemIndex
に設定してから、DataList の DataBind()
メソッドを呼び出して DataList にデータを再バインドします。
このイベント ハンドラーを追加した後、ブラウザーでページを見直します。 [編集] ボタンをクリックすると、クリックした製品が編集可能になります (図 13 を参照)。
図 13: [編集] ボタンをクリックすると、製品が編集可能になります (クリックしてフルサイズの画像を表示)
手順 6: ユーザーの変更を保存する
編集した製品の [更新] または [キャンセル] ボタンをクリックしても、この時点では何も行われません。この機能を追加するには、DataList の UpdateCommand
と CancelCommand
イベントのイベント ハンドラーを作成する必要があります。 まず、CancelCommand
イベント ハンドラーを作成します。このハンドラーは、編集された製品の [キャンセル] ボタンがクリックされ、DataList を編集前の状態に戻すタスクが指示されたときに実行されます。
DataList がそのすべての項目を読み取り専用モードでレンダリングするには、次の操作を行う必要があります。
- DataList の
EditItemIndex
プロパティを、存在しないDataListItem
インデックスのインデックスに設定します。-1
は安全な選択肢です。DataListItem
インデックスは0
から始まるためです。 - データを DataList に再バインドします。 DataList の
EditItemIndex
に対応するDataListItem
ItemIndex
がないため、DataList 全体が読み取り専用モードでレンダリングされます。
これらの手順は、次のイベント ハンドラー コードを使用して実行できます。
protected void DataList1_CancelCommand(object source, DataListCommandEventArgs e)
{
// Set the DataList's EditItemIndex property to -1
DataList1.EditItemIndex = -1;
// Rebind the data to the DataList
DataList1.DataBind();
}
さらに、[キャンセル] ボタンをクリックすると、DataList が編集前の状態に戻ります。
最後に完了する必要があるイベント ハンドラーは、UpdateCommand
イベント ハンドラーです。 このイベント ハンドラーでは、次の操作を行う必要があります。
- プログラムを使用して、ユーザーが入力した製品名と価格、および編集された製品の
ProductID
にアクセスします。 ProductsBLL
クラスで適切なUpdateProduct
オーバーロードを呼び出して、更新プロセスを開始します。- DataList の
EditItemIndex
プロパティを、存在しないDataListItem
インデックスのインデックスに設定します。-1
は安全な選択肢です。DataListItem
インデックスは0
から始まるためです。 - データを DataList に再バインドします。 DataList の
EditItemIndex
に対応するDataListItem
ItemIndex
がないため、DataList 全体が読み取り専用モードでレンダリングされます。
手順 1 と 2 は、ユーザーの変更を保存する責任を担います。手順 3 と 4 では、変更が保存された後に DataList を編集前の状態に戻します。CancelCommand
イベント ハンドラーで実行される手順と同じです。
更新された製品名と価格を取得するには、FindControl
メソッドを使用してプログラムで EditItemTemplate
の TextBox Web コントロールを参照する必要があります。 また、編集した製品の ProductID
値を取得する必要があります。 最初に ObjectDataSource を DataList にバインドしたとき、Visual Studio では DataList の DataKeyField
プロパティをデータ ソース (ProductID
) の主キー値に割り当てしました。 この値は、DataList の DataKeys
コレクションから取得できます。 少し時間を使って、DataKeyField
プロパティが実際に ProductID
に設定されていることを確認します。
次のコードは、4 つの手順を実装します。
protected void DataList1_UpdateCommand(object source, DataListCommandEventArgs e)
{
// Read in the ProductID from the DataKeys collection
int productID = Convert.ToInt32(DataList1.DataKeys[e.Item.ItemIndex]);
// Read in the product name and price values
TextBox productName = (TextBox)e.Item.FindControl("ProductName");
TextBox unitPrice = (TextBox)e.Item.FindControl("UnitPrice");
string productNameValue = null;
if (productName.Text.Trim().Length > 0)
productNameValue = productName.Text.Trim();
decimal? unitPriceValue = null;
if (unitPrice.Text.Trim().Length > 0)
unitPriceValue = Decimal.Parse(unitPrice.Text.Trim(),
System.Globalization.NumberStyles.Currency);
// Call the ProductsBLL's UpdateProduct method...
ProductsBLL productsAPI = new ProductsBLL();
productsAPI.UpdateProduct(productNameValue, unitPriceValue, productID);
// Revert the DataList back to its pre-editing state
DataList1.EditItemIndex = -1;
DataList1.DataBind();
}
イベント ハンドラーは、DataKeys
コレクションから編集された製品の ProductID
を読み取ることで開始します。 次に、EditItemTemplate
の 2 つの TextBox が参照され、その Text
プロパティがローカル変数 productNameValue
と unitPriceValue
に格納されます。 Decimal.Parse()
メソッドを使用して UnitPrice
TextBox から値を読み取り、入力された値に通貨記号が含まれている場合でも Decimal
値に正しく変換できるようにします。
Note
TextBox の Text プロパティに値が指定されている場合、ProductName
と UnitPrice
TextBox の値は productNameValue 変数と unitPriceValue 変数にのみ割り当てられます。 それ以外の場合は、値 Nothing
が変数に使用され、データベース NULL
値を使用してデータを更新する効果があります。 つまり、このコードでは、空の文字列をデータベース NULL
値に変換します。これは、GridView、DetailsView、FormView コントロールの編集インターフェイスの既定の動作です。
値を読み取った後、ProductsBLL
クラス の UpdateProduct
メソッドが呼び出され、製品の名前、価格、ProductID
が渡されます。 イベント ハンドラーは、CancelCommand
イベント ハンドラーとまったく同じロジックを使用して、DataList を編集前の状態に戻すことによって完了します。
EditCommand
、CancelCommand
、UpdateCommand
イベント ハンドラーが完了すると、訪問者は製品の名前と価格を編集できます。 図 14 から 16 は、この編集ワークフローの動作を示しています。
図 14: 最初にページにアクセスすると、すべての製品が読み取り専用モードになります (クリックしてフルサイズの画像を表示)
図 15: 製品名または価格を更新するには、[編集] ボタンをクリックします (クリックしてフルサイズの画像を表示)
図 16: 値を変更した後、[更新] をクリックして読み取り専用モードに戻ります (クリックしてフルサイズの画像を表示)
手順 7: 削除機能の追加
DataList に削除機能を追加する手順は、編集機能を追加する手順と似ています。 要するに、クリックしたときに ItemTemplate
に削除ボタンを追加する必要があります。
DataKeys
コレクションを介して、対応する製品のProductID
を読み取ります。ProductsBLL
クラス のDeleteProduct
メソッドを呼び出して削除を実行します。- データを DataList に再バインドします。
まず、[削除] ボタンを ItemTemplate
に追加します。
クリックすると、CommandName
が Edit、Update、または Cancel のボタンは、追加のイベントと共に DataList の ItemCommand
イベントを発生させます (たとえば、Edit を使用すると EditCommand
イベントも発生します)。 同様に、CommandName
プロパティが Delete に設定されている DataList 内の Button、LinkButton、または ImageButton では、DeleteCommand
イベントが発生します (ItemCommand
と共に)。
ItemTemplate
の [編集] ボタンの横に [削除] ボタンを追加し、その CommandName
プロパティを Delete に設定します。 この Button コントロールを追加すると、DataList の ItemTemplate
宣言構文は次のようになります。
<ItemTemplate>
<h5>
<asp:Label runat="server" ID="ProductNameLabel"
Text='<%# Eval("ProductName") %>' />
</h5>
Price: <asp:Label runat="server" ID="Label1"
Text='<%# Eval("UnitPrice", "{0:C}") %>' />
<br />
<asp:Button runat="server" id="EditProduct" CommandName="Edit"
Text="Edit" />
<asp:Button runat="server" id="DeleteProduct" CommandName="Delete"
Text="Delete" />
<br />
<br />
</ItemTemplate>
次に、次のコードを使用して、DataList の DeleteCommand
イベントのイベント ハンドラーを作成します。
protected void DataList1_DeleteCommand(object source, DataListCommandEventArgs e)
{
// Read in the ProductID from the DataKeys collection
int productID = Convert.ToInt32(DataList1.DataKeys[e.Item.ItemIndex]);
// Delete the data
ProductsBLL productsAPI = new ProductsBLL();
productsAPI.DeleteProduct(productID);
// Rebind the data to the DataList
DataList1.DataBind();
}
[削除] ボタンをクリックするとポストバックが発生し、DataList の DeleteCommand
イベントが発生します。 イベント ハンドラーでは、クリックされた製品の ProductID
値が DataKeys
コレクションからアクセスされます。 次に、ProductsBLL
クラスの DeleteProduct
メソッドを呼び出して製品を削除します。
製品を削除した後、DataList (DataList1.DataBind()
) にデータを再バインドすることが重要です。そうしないと、DataList は削除された製品を引き続き表示します。
まとめ
DataList には、GridView で利用できるポイント アンド クリックの編集と削除のサポートがありませんが、短いコードでこれらの機能を含むように拡張できます。 このチュートリアルでは、削除可能で名前と価格を編集できる製品の 2 列の一覧を作成する方法について説明しました。 編集と削除のサポートの追加とは、適切な Web コントロール ItemTemplate
と EditItemTemplate
を含め、対応するイベント ハンドラーを作成し、ユーザーが入力した値と主キーの値を読み取り、ビジネス ロジック レイヤーとやり取りすることです。
DataList には基本的な編集機能と削除機能が追加されていますが、より高度な機能はありません。 たとえば、入力フィールドの検証はありません。ユーザーが "Too expensive" という価格を入力した場合、"Too expensive" を Decimal
に変換しようとすると、Decimal.Parse
から例外がスローされます。 同様に、ビジネス ロジックまたはデータ アクセス レイヤーでデータの更新に問題がある場合、ユーザーには標準エラー画面が表示されます。 [削除] ボタンに何らかの確認がなければ、誤って製品を削除する可能性が高すぎます。
今後のチュートリアルでは、編集のユーザー エクスペリエンスを向上させる方法について説明します。
プログラミングに満足!
著者について
7 冊の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジに取り組んでいます。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。
特別な感謝
このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、Zack Jones、Ken Pespisa、Randy Schmidt でした。 今後の MSDN の記事を確認することに関心がありますか? その場合は、 にmitchell@4GuysFromRolla.com行をドロップしてください。