DetailsView コントロールで TemplateFields を使用する (C#)
GridView で使用できるのと同じ TemplateFields 機能は、DetailsView コントロールでも使用できます。 このチュートリアルでは、TemplateFields を含む DetailsView を使用して、一度に 1 つの製品を表示します。
はじめに
TemplateField は、BoundField、CheckBoxField、HyperLinkField、およびその他のデータ フィールド コントロールよりも高い柔軟性でデータをレンダリングできます。 前の チュートリアル では、GridView で TemplateField を使用して以下を行いました。
- 1 つの列に複数のデータ フィールド値を表示します。 具体的には、 フィールドと
LastName
フィールドの両方がFirstName
1 つの GridView 列に結合されました。 - 代替 Web コントロールを使用して、データ フィールド値を表します。 Calendar コントロールを使用して値を
HiredDate
表示する方法を確認しました。 - 基になるデータに基づいて状態情報を表示します。 テーブルには
Employees
、従業員がジョブに参加した日数を返す列は含まれていませんが、前のチュートリアルの GridView の例では、TemplateField メソッドと書式設定メソッドを使用して、このような情報を表示できました。
GridView で使用できるのと同じ TemplateFields 機能は、DetailsView コントロールでも使用できます。 このチュートリアルでは、2 つの TemplateFields を含む DetailsView を使用して、一度に 1 つの製品を表示します。 最初の TemplateField は、、UnitsInStock
、および UnitsOnOrder
データ フィールドを UnitPrice
1 つの DetailsView 行に結合します。 2 番目の TemplateField はフィールドの値を Discontinued
表示しますが、 が の場合は "YES" を表示し、それ以外の場合 Discontinued
は true
"NO" を表示する書式設定メソッドを使用します。
図 1: 2 つの TemplateFields を使用してディスプレイをカスタマイズする (フルサイズの画像を表示するをクリックします)
それでは作業を始めましょう。
手順 1: データを DetailsView にバインドする
前のチュートリアルで説明したように、TemplateFields を使用する場合は、多くの場合、BoundFields のみを含む DetailsView コントロールを作成してから、新しい TemplateFields を追加するか、必要に応じて既存の BoundFields を TemplateFields に変換するのが最も簡単です。 そのため、このチュートリアルを開始するには、Designerを使用して DetailsView をページに追加し、製品の一覧を返す ObjectDataSource にバインドします。 これらの手順では、製品のブール以外の値フィールドごとに BoundFields を使用して DetailsView を作成し、1 つのブール値フィールド (廃止) の CheckBoxField を作成します。
ページをDetailsViewTemplateField.aspx
開き、DetailsView をツールボックスからDesignerにドラッグします。 DetailsView のスマート タグから、クラスGetProducts()
のメソッドを呼び出す新しい ObjectDataSource コントロールをProductsBLL
追加することを選択します。
図 2: メソッドを呼び出す新しい ObjectDataSource コントロールを GetProducts()
追加する (フルサイズの画像を表示する場合はクリックします)
このレポートでは、 ProductID
、 SupplierID
、 CategoryID
、および ReorderLevel
BoundFields を削除します。 次に、BoundFields を並べ替えて、 CategoryName
と SupplierName
BoundFields が BoundField の直後に ProductName
表示されるようにします。 必要に応じて BoundFields の HeaderText
プロパティと書式設定プロパティを自由に調整できます。 GridView と同様に、これらの BoundField レベルの編集は、[フィールド] ダイアログ ボックス (DetailsView のスマート タグの [フィールドの編集] リンクをクリックしてアクセス可能) または宣言型構文を使用して実行できます。 最後に、表示されるデータに基づいて DetailsView Height
コントロールを展開し、スマート タグの [ページングを有効にする] チェック ボックスをチェックするために、DetailsView の および Width
プロパティの値をクリアします。
これらの変更を行った後、DetailsView コントロールの宣言型マークアップは次のようになります。
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"
EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName" HeaderText="Supplier"
ReadOnly="True" SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice" HeaderText="Price"
SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock"
HeaderText="Units In Stock" SortExpression="UnitsInStock" />
<asp:BoundField DataField="UnitsOnOrder"
HeaderText="Units On Order" SortExpression="UnitsOnOrder" />
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>
ブラウザーを使用してページを表示します。 この時点で、製品の名前、カテゴリ、仕入先、価格、在庫単位、注文単位、および廃止された状態を示す行が表示された 1 つの製品 (Chai) が表示されます。
図 3: 製品の詳細は、一連の BoundFields を使用して表示されます (フルサイズの画像を表示する場合はクリックします)
手順 2: 価格、在庫単位、および注文単位を 1 行にまとめる
DetailsView には、および UnitsOnOrder
フィールドのUnitPrice
UnitsInStock
行があります。 これらのデータ フィールドは、新しい TemplateField を追加するか、既存 UnitPrice
の 、 UnitsInStock
、および BoundFields のいずれかを TemplateField に変換することで、TemplateField を使用して UnitsOnOrder
1 つの行に結合できます。 私は個人的に既存の BoundFields を変換することを好みますが、新しい TemplateField を追加して練習しましょう。
まず、DetailsView のスマート タグの [フィールドの編集] リンクをクリックして、[フィールド] ダイアログ ボックスを表示します。 次に、新しい TemplateField を追加し、その HeaderText
プロパティを "Price and Inventory" に設定し、BoundField の上に配置されるように新しい TemplateField を UnitPrice
移動します。
図 4: DetailsView コントロールに新しい TemplateField を追加する (フルサイズの画像を表示するをクリックします)
この新しい TemplateField には、および UnitsOnOrder
BoundFields に現在表示されている値が含まれるのでUnitPrice
UnitsInStock
、それらを削除しましょう。
この手順の最後のタスクは、Price と Inventory TemplateField のマークアップを定義ItemTemplate
することです。これは、Designerの DetailsView のテンプレート編集インターフェイスを使用するか、コントロールの宣言構文を使用して手動で行うことができます。 GridView と同様に、DetailsView のテンプレート編集インターフェイスにアクセスするには、スマート タグの [テンプレートの編集] リンクをクリックします。 ここから、編集するテンプレートをドロップダウン リストから選択し、[ツールボックス] から任意の Web コントロールを追加できます。
このチュートリアルでは、まず Price および Inventory TemplateField ItemTemplate
の に Label コントロールを追加します。 次に、Label Web コントロールのスマート タグから [Edit DataBindings]\(DataBindings の編集\) リンクをクリックし、プロパティをText
UnitPrice
フィールドにバインドします。
図 5: ラベルの Text
プロパティをデータ フィールドに UnitPrice
バインドする (フルサイズの画像を表示する 場合はクリックします)
価格を通貨として書式設定する
この追加により、ラベル Web コントロールの [価格] と [在庫テンプレート] フィールドに、選択した製品の価格だけが表示されるようになります。 図 6 は、ブラウザーから見たときのこれまでの進行状況のスクリーン ショットを示しています。
図 6: [価格] と [在庫テンプレート] フィールドに価格が表示されます (フルサイズの画像を表示する場合をクリックします)
製品の価格は通貨として書式設定されていないことに注意してください。 BoundField では、 プロパティを に設定しDataFormatString
、 プロパティを HtmlEncode
にfalse
設定することで、書式設定を行{0:formatSpecifier}
うことができます。 ただし、TemplateField の場合、書式設定命令は、データバインド構文で指定するか、アプリケーションのコード内のどこかで定義された書式設定メソッドを使用して指定する必要があります (ASP.NET ページの分離コード クラスなど)。
Label Web コントロールで使用されるデータバインド構文の書式を指定するには、ラベルのスマート タグから [DataBindings の編集] リンクをクリックして [DataBindings] ダイアログ ボックスに戻ります。 書式設定手順は、[書式] ドロップダウン リストに直接入力することも、定義されている書式指定文字列のいずれかを選択することもできます。 BoundField DataFormatString
の プロパティと同様に、書式設定は を使用して {0:formatSpecifier}
指定されます。
フィールドには UnitPrice
、適切なドロップダウン リスト値を選択するか、手動で {0:C}
入力して指定された通貨書式を使用します。
図 7: 価格を通貨として書式設定する (フルサイズの画像を表示する] をクリックします)
宣言によって、書式設定の仕様は、 メソッドまたは Eval
メソッドの 2 番目のBind
パラメーターとして示されます。 Designerによって行われた設定により、宣言型マークアップで次の databinding 式が生成されます。
<asp:Label ID="Label1" runat="server" Text='<%# Eval("UnitPrice", "{0:C}") %>'/>
TemplateField への残りのデータ フィールドの追加
この時点で、Price と Inventory TemplateField にデータ フィールドをUnitPrice
表示および書式設定しましたが、 フィールドと UnitsOnOrder
フィールドを表示UnitsInStock
する必要があります。 これらを価格の下の行とかっこで囲んで表示しましょう。 Designerのテンプレート編集インターフェイスから、このようなマークアップを追加するには、テンプレート内にカーソルを置き、表示するテキストを入力するだけです。 または、このマークアップを宣言構文に直接入力することもできます。
静的マークアップ、Label Web コントロール、およびデータバインド構文を追加して、Price と Inventory TemplateField に次のような価格と在庫情報が表示されるようにします。
UnitPrice
(在庫/ オンオーダー:UnitsInStock / UnitsOnOrder)
このタスクを実行すると、DetailsView の宣言型マークアップは次のようになります。
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"
EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductName"
HeaderText="Product" SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName"
HeaderText="Supplier" ReadOnly="True"
SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
<asp:TemplateField HeaderText="Price and Inventory">
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Eval("UnitPrice", "{0:C}") %>'></asp:Label>
<br />
<strong>
(In Stock / On Order: </strong>
<asp:Label ID="Label2" runat="server"
Text='<%# Eval("UnitsInStock") %>'></asp:Label>
<strong>/</strong>
<asp:Label ID="Label3" runat="server"
Text='<%# Eval("UnitsOnOrder") %>'>
</asp:Label><strong>)</strong>
</ItemTemplate>
</asp:TemplateField>
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>
これらの変更により、価格と在庫の情報が 1 つの DetailsView 行に統合されました。
図 8: 価格と在庫情報が 1 行に表示される (フルサイズの画像を表示する場合はクリックします)
手順 3: 廃止されたフィールド情報のカスタマイズ
Products
テーブルのDiscontinued
列は、製品が廃止されたかどうかを示すビット値です。 DetailsView (または GridView) をデータ ソース コントロールにバインドする場合、 などのDiscontinued
ブール値フィールドは CheckBoxFields として実装されますが、ProductID
ProductName
ブール値以外のフィールド (、、など) は BoundFields として実装されます。 CheckBoxField は、データ フィールドの値が True の場合にチェックされ、それ以外の場合はオフになっている無効なチェック ボックスとしてレンダリングされます。
CheckBoxField を表示するのではなく、製品が廃止されたかどうかを示すテキストを表示することをお勧めします。 これを実現するには、DetailsView から CheckBoxField を削除し、プロパティが に設定されている BoundField DataField
を Discontinued
追加します。 しばらくお待ちください。 この変更の後、DetailsView には、廃止された製品のテキスト "True" と、アクティブな製品の "False" というテキストが表示されます。
図 9: 文字列 True と False は、廃止された状態を表示するために使用されます (フルサイズの画像を表示するをクリックします)
文字列 "True" または "False" は使用せず、代わりに "YES" と "NO" を使用するとします。 このようなカスタマイズは、TemplateField と書式設定メソッドを使用して実行できます。 書式設定メソッドは任意の数の入力パラメーターを受け取ることができますが、テンプレートに挿入するには HTML を (文字列として) 返す必要があります。
入力パラメーターとしてブール値を DetailsViewTemplateField.aspx
受け取り、文字列を返す という名前 DisplayDiscontinuedAsYESorNO
のページの分離コード クラスに書式設定メソッドを追加します。 前のチュートリアルで説明したように、テンプレートからアクセスできるようにするには、このメソッドを または public
としてprotected
マークする必要があります。
protected string DisplayDiscontinuedAsYESorNO(bool discontinued)
{
if (discontinued)
return "YES";
else
return "NO";
}
このメソッドは、入力パラメーター (discontinued
) をチェックし、それ以外の場合は "NO" の場合は true
"YES" を返します。
注意
前のチュートリアルで調べた書式設定メソッドでは、 を含むNULL
データ フィールドを渡していたため、従業員HiredDate
のプロパティ値にデータベースNULL
値がある場合にチェックする必要があったことをEmployeesRow
HiredDate
思い出してください。 列にデータベースNULL
値を割り当てることはできないため、Discontinued
このようなチェックはここでは必要ありません。 さらに、 メソッドが インスタンスまたは 型のパラメーターを受け入れる必要なく、ブール型の入力パラメーターを受け取 ProductsRow
ることができるのはこのためです object
。
この書式設定メソッドが完了したら、残っているのは TemplateField ItemTemplate
の から呼び出す必要があります。 TemplateField を作成するには、BoundField を Discontinued
削除して新しい TemplateField を追加するか、BoundField を Discontinued
TemplateField に変換します。 次に、宣言型マークアップ ビューから TemplateField を編集し、現在のインスタンスDiscontinued
の プロパティのProductRow
値を渡して、 メソッドを呼び出す DisplayDiscontinuedAsYESorNO
ItemTemplate だけが含まれるようにします。 これは、 メソッドを Eval
使用してアクセスできます。 具体的には、TemplateField のマークアップは次のようになります。
<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
<ItemTemplate>
<%# DisplayDiscontinuedAsYESorNO((bool)
Eval("Discontinued")) %>
</ItemTemplate>
</asp:TemplateField>
これにより、DetailsView をDisplayDiscontinuedAsYESorNO
レンダリングするときにメソッドが呼び出され、インスタンスのDiscontinued
値がProductRow
渡されます。 メソッドは Eval
型 object
の値を返しますが、 DisplayDiscontinuedAsYESorNO
メソッドは 型 bool
の入力パラメーターを必要とするため、メソッドの Eval
戻り値を に bool
キャストします。 メソッドは DisplayDiscontinuedAsYESorNO
、受け取る値に応じて "YES" または "NO" を返します。 戻り値は、この DetailsView 行に表示される値です (図 10 を参照)。
図 10: [はい] または [NO] の値が [廃止] 行に表示されるようになりました (フルサイズの画像を表示する をクリックします)
まとめ
DetailsView コントロールの TemplateField を使用すると、他のフィールド コントロールで使用できるよりも高い柔軟性でデータを表示でき、次のような状況に最適です。
- 1 つの GridView 列に複数のデータ フィールドを表示する必要がある
- データは、プレーン テキストではなく Web コントロールを使用して最適に表現されます
- 出力は、メタデータの表示やデータの再フォーマットなど、基になるデータによって異なります
TemplateFields を使用すると、DetailsView の基になるデータのレンダリングをより柔軟に行うことができますが、各フィールドが HTML <table>
内の行としてレンダリングされるため、DetailsView 出力は少しボックスな感じがします。
FormView コントロールは、レンダリングされた出力を構成する際の柔軟性を高めます。 FormView にはフィールドではなく、一連のテンプレート (ItemTemplate
、、EditItemTemplate
HeaderTemplate
など) が含まれています。 次のチュートリアルでは、FormView を使用してレンダリングされたレイアウトをさらに制御する方法について説明します。
幸せなプログラミング!
著者について
7 冊の ASP/ASP.NET 書籍の著者であり、 4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジと協力しています。 Scott は独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズ・ティーチ・自分自身 ASP.NET 24時間で2.0です。 にアクセスmitchell@4GuysFromRolla.comすることも、ブログを介して アクセスすることもできます。これは でhttp://ScottOnWriting.NET確認できます。
特別な感謝
このチュートリアル シリーズは、多くの役立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は Dan Jagers でした。 今後の MSDN 記事の確認に関心がありますか? その場合は、 に行mitchell@4GuysFromRolla.comをドロップしてください。
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示