DetailsView コントロールで TemplateFields を使用する (VB)

作成者: Scott Mitchell

PDF のダウンロード

GridView で使用できる TemplateFields 機能は、DetailsView コントロールでも使用できます。 このチュートリアルでは、TemplateFields を含む DetailsView を使用して、一度に 1 つの製品を表示します。

はじめに

TemplateField は、BoundField、CheckBoxField、HyperLinkField といったデータ フィールド コントロールよりも高い柔軟性でデータをレンダリングできます。 前のチュートリアルでは、GridView で TemplateField を使用して次のことを行いました。

  • 1 つの列に複数のデータ フィールド値を表示する。 具体的には、FirstName フィールドと LastName フィールドの両方を 1 つの GridView 列に結合しました。
  • 代替 Web コントロールを使用してデータ フィールド値を表示する。 Calendar コントロールを使用して HiredDate 値を表示する方法について説明しました。
  • 基になるデータに基づいてステータス情報を表示する。 Employees テーブルには従業員が勤務した日数を返す列は含まれていませんが、前のチュートリアルの GridView の例では、TemplateField と書式設定方法を使用してこのような情報を表示できました。

GridView で使用できる TemplateFields 機能は、DetailsView コントロールでも使用できます。 このチュートリアルでは、2 つの TemplateFields を含む DetailsView を使用して、一度に 1 つの製品を表示します。 最初の TemplateField では、UnitPrice データ フィールド、UnitsInStock データ フィールド、UnitsOnOrder データフィールドが 1 つの DetailsView 行に結合されます。 2 番目の TemplateField には Discontinued フィールドの値が表示されますが、DiscontinuedTrue の場合は書式設定方法を使用して "YES" と表示され、それ以外の場合は "NO" と表示されます。

2 つの TemplateFields を使用して表示をカスタマイズする

図 1: TemplateField を 2 つ使用したディスプレイのカスタマイズ (クリックすると全画面表示されます)

それでは始めましょう。

手順 1: データを DetailsView にバインドする

前のチュートリアルで説明したように、TemplateField を使用する場合は、最初に BoundField のみを含む DetailsView コントロールを作成してから新しい TemplateField を追加するか、必要に応じて既存の BoundField を TemplateField に変換する方法が最も簡単なことが多いです。 そのため、このチュートリアルでも、最初にデザイナーを使用して DetailsView をページに追加し、製品の一覧を返す ObjectDataSource にバインドします。 これらの手順では、製品のブール値以外の各フィールドには BoundField を使用し、ブール値フィールドには CheckBoxField を使用 (廃止) して DetailsView を作成します。

DetailsViewTemplateField.aspx ページを開き、DetailsView をツールボックスからデザイナーにドラッグします。 DetailsView のスマート タグから、ProductsBLL クラスの GetProducts() メソッドを呼び出す新しい ObjectDataSource コントロールを選択して追加します。

GetProducts() メソッドを呼び出す新しい ObjectDataSource コントロールを追加する

図 2: GetProducts() メソッドを呼び出す新しい ObjectDataSource コントロールの追加 (クリックすると全画面表示されます)

このレポートでは、ProductIDSupplierIDCategoryIDReorderLevel の各 BoundField を削除します。 次に、BoundField を並べ替えて、CategoryNameBoundField と SupplierName BoundField が ProductName BoundField の直後に表示されるようにします。 BoundFields の HeaderText プロパティや書式設定プロパティは、必要に応じて自由に調整できます。 GridView と同様に、これらの BoundField レベルの編集は、[フィールド] ダイアログ ボックス (DetailsView のスマート タグの [フィールドの編集] リンクをクリックしてアクセス可能) または宣言構文を使用して実行できます。 最後に、DetailsView コントロールを表示されたデータに基づいて展開できるように、DetailsView の Height プロパティ値と 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) が表示されます。

製品の詳細は、一連の BoundFields を使用して表示されます

図 3: 一連の BoundField を使用して表示された製品の詳細 (クリックすると全画面表示されます)

手順 2: 注文時の価格、在庫単位、注文単位を 1 行に結合する

DetailsView には、UnitPriceUnitsInStockUnitsOnOrder の各フィールドに対応する行があります。 これらのデータ フィールドは、TemplateField を使用して 1 つの行に結合できます。結合するには、新しい TemplateField を追加するか、既存の UnitPriceUnitsInStockUnitsOnOrder の各 BoundField のいずれかを TemplateField に変換します。 個人的には既存の BoundFields を変換する方法が好きなのですが、ここでは新しい TemplateField を追加して結合する練習を行いましょう。

まず、DetailsView のスマート タグに含まれる [フィールドの編集] リンクをクリックして、[フィールド] ダイアログ ボックスを表示します。 次に、新しい TemplateField を追加し、その HeaderText プロパティを [Price and Inventory]\(価格と在庫\) に設定して、UnitPrice BoundField の上に配置されるように新しい TemplateField を 移動します。

DetailsView コントロールに新しい TemplateField を追加する

図 4: DetailsView コントロールに新しい TemplateField を追加 (クリックすると全画面表示されます)

この新しい TemplateField には、現在 UnitPriceUnitsInStockUnitsOnOrder の各 BoundField に表示されている値が含まれるので、それらの値を削除しましょう。

この手順の最後のタスクでは、[Price and Inventory]\(価格と在庫\) TemplateField の ItemTemplate マークアップを定義します。これは、デザイナーで DetailsView のテンプレート編集インターフェイスを使用するか、コントロールの宣言構文を使用して手動で行うことができます。 GridView と同様に、DetailsView のテンプレート編集インターフェイスには、スマート タグの [テンプレートの編集] リンクをクリックしてアクセスできます。 ここで、編集するテンプレートをドロップダウン リストから選択し、ツールボックスから任意の Web コントロールを追加できます。

このチュートリアルでは、まず [Price and Inventory]\(価格と在庫\) TemplateField の ItemTemplate に Label コントロールを追加します。 次に、Label Web コントロールのスマート タグから [DataBindings の編集] リンクをクリックし、Text プロパティを UnitPrice フィールドにバインドします。

ラベルの Text プロパティを UnitPrice データ フィールドにバインドする

図 5: Label の Text プロパティを UnitPrice データ フィールドにバインド (クリックすると全画面表示されます)

価格を通貨形式に書式設定する

この形式を追加することで、Label Web コントロールの [Price and Inventory]\(価格と在庫\) TemplateField には、選択した製品の価格だけが表示されるようになります。 図 6 は、ブラウザーを使用して表示した場合の、これまでの経過を示すスクリーン ショットです。

Price と Inventory TemplateField に価格が表示される

図 6: [Price and Inventory]\(価格と在庫\) TemplateField に表示された価格 (クリックすると全画面表示されます)

製品の価格が通貨形式に書式設定されていないことに注意してください。 BoundField を使用すると、HtmlEncode プロパティを False に設定し、DataFormatString プロパティを {0:formatSpecifier} に設定することで書式設定を行えます。 ただし、TemplateField の場合は、書式設定命令をデータ バインド構文で、またはアプリケーションのコード内のいずれか (ASP.NET ページの分離コード クラスなど) で定義されている書式設定方法を使用して指定する必要があります。

Label Web コントロールで使用されるデータバインド構文の書式を指定するには、Label のスマート タグから [DataBindings の編集] リンクをクリックして [DataBindings] ダイアログ ボックスに戻ります。 書式設定命令は、[書式] ドロップダウン リストに直接入力することも、定義済みの書式指定文字列のいずれかを選択することも可能です。 BoundField の DataFormatString プロパティと同様に、書式設定は {0:formatSpecifier} を使用して指定されます。

UnitPrice フィールドには、適切なドロップダウン リスト値を選択するか、{0:C} に手動で入力して指定した通貨書式を使用します。

価格を通貨として書式設定する

図 7: 価格を通貨形式に設定 (クリックすると全画面表示されます)

宣言によって、書式設定の仕様は、2 番目のパラメーターとして Bind または Eval メソッドに示されます。 デザイナーを使用して行われた設定により、宣言型マークアップでは次のデータバインド式が生成されます。

<asp:Label ID="Label1" runat="server" Text='<%# Eval("UnitPrice", "{0:C}") %>'/>

残りのデータ フィールドを TemplateField に追加する

この時点で、[Price and Inventory]\(価格と在庫\) TemplateField に UnitPrice データ フィールドを表示および書式設定しましたが、さらに UnitsInStock フィールドと UnitsOnOrder フィールドも表示する必要があります。 では、これらのフィールドを価格の下の行にかっこ付きで表示していきましょう。 デザイナーのテンプレート編集インターフェイスからこのようなマークアップを追加するには、テンプレート内にカーソルを置き、表示するテキストを入力します。 または、このマークアップを宣言構文に直接入力することもできます。

静的マークアップ、Label Web コントロール、およびデータバインド構文を追加して、次のように [Price and 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 行に統合されました。

価格情報と在庫情報が 1 行で表示される

図 8: 1 行に表示された価格と在庫情報 (クリックすると全画面表示されます)

手順 3: 生産停止されたフィールド情報のカスタマイズ

Products テーブルの Discontinued 列は、製品が生産停止されたかどうかを示すビット値です。 DetailsView (または GridView) をデータ ソース コントロールにバインドする場合、ブール値フィールド (Discontinued など) は CheckBoxField として実装されますが、ブール値以外のフィールド (ProductIDProductName など) は BoundField として実装されます。 CheckBoxField は、無効なチェックボックスとしてレンダリングされます。このボックスは、データ フィールドの値が [True] の場合にチェックされ、それ以外の場合はチェック解除されます。

CheckBoxField を表示するのではなく、製品が生産停止になったかどうかを示すテキストを表示することもできます。 このテキストを表示するには、DetailsView から CheckBoxField を削除してから、DataField プロパティが Discontinued に設定されている BoundField を追加します。 少し時間を取って行ってください。 変更後、生産停止された製品の場合は DetailsView に "True" というテキストが表示され、依然として生産中の製品の場合は "False" というテキストが表示されます。

文字列 True と False は、廃止された状態を表示するために使用されます

図 9: 生産停止の状態を表示する文字列 True と False (クリックすると全画面表示されます)

文字列 "True" または "False" ではなく、"YES" と "NO" を使用したい場合は、 TemplateField と書式設定方法を使用してカスタマイズできます。 書式設定方法では任意の数の入力パラメーターを使用できますが、テンプレートに挿入するには HTML を文字列として返す必要があります。

書式設定方法を DetailsViewTemplateField.aspx ページの DisplayDiscontinuedAsYESorNO という名前の分離コード クラスに追加して、Northwind.ProductsRow オブジェクトを入力パラメーターとして受け取り、文字列を返します。 前のチュートリアルで説明したように、テンプレートからアクセスできるようにするには、このメソッドを Protected または Public としてマークする必要があります

Protected Function DisplayDiscontinuedAsYESorNO(discontinued As Boolean) As String
    If discontinued Then
        Return "YES"
    Else
        Return "NO"
    End If
End Function

このメソッドでは、入力パラメーター (discontinued) を確認し、True の場合は "YES" と返し、それ以外の場合は "NO" と返します。

Note

前のチュートリアルで調べた書式設定方法では、NULL を含むデータ フィールドを渡していたため、EmployeesRowHiredDate プロパティにアクセスする前に、従業員の HiredDate プロパティ値にデータベースの NULL 値が含まれているかを確認する必要がありました。 Discontinued 列にはデータベースの NULL 値を割り当てることができないため、ここではこのようなチェックは必要ありません。 さらに、ProductsRow インスタンスや Object タイプのパラメーターを受け入れる必要はなく、ブール型の入力パラメーターを 受け入れることができるのもこのためです。

この書式設定方法が完了したら、最後に TemplateField の ItemTemplate から呼び出す必要があります。 TemplateField を作成するには、Discontinued BoundField を削除して新しい TemplateField を追加するか、Discontinued BoundField を TemplateField に変換します。 次に、宣言型マークアップ ビューで TemplateField を編集し、現在の ProductRow インスタンスの Discontinued プロパティの値を渡して DisplayDiscontinuedAsYESorNO メソッドを呼び出す ItemTemplate だけを含めるようにします。 これにより、Eval メソッドを使用してアクセスできるようになります。 具体的には、TemplateField のマークアップは次のようになります。

<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
    <ItemTemplate>
        <%#DisplayDiscontinuedAsYESorNO(Convert.ToBoolean(Eval("Discontinued")))%> 
    </ItemTemplate>
</asp:TemplateField>

これにより、DetailsView をレンダリングすると ProductRow インスタンスの Discontinued 値を渡して DisplayDiscontinuedAsYESorNO メソッドが呼び出されます。 Eval メソッドは Object タイプの値を返しますが、DisplayDiscontinuedAsYESorNO メソッドでは Boolean タイプの入力パラメーターが期待されるため、Eval メソッドの戻り値を Boolean にキャストします。 次に、DisplayDiscontinuedAsYESorNO メソッドは受け取る値に応じて "YES" または "NO" を返します。 戻り値は、この DetailsView 行に表示される値です (図 10 を参照)。

廃止された行に YES 値または NO 値が表示されるようになりました

図 10: [生産中止] 行に表示された YES または NO 値 (クリックすると全画面表示されます)

まとめ

DetailsView コントロールの TemplateField を使用すると、他のフィールド コントロールで使用するよりも高い柔軟性でデータを表示できます。これは、次の状況において最適です。

  • 1 つの GridView 列に複数のデータ フィールドを表示する必要がある場合
  • プレーン テキストではなく Web コントロールを使用してデータ表示するのが最適な場合
  • 出力が基になるデータ (メタデータの表示やデータの再フォーマットなど) に依存している場合

TemplateFields を使用すると、DetailsView の基になるデータのレンダリングをより柔軟に行うことができますが、各フィールドが HTML <table> の行としてレンダリングされるため、DetailsView の出力がやや小さく見えます。

FormView コントロールでは、レンダリングされた出力をより柔軟に構成することができます。 FormView には、フィールドではなく一連のテンプレート (ItemTemplateEditItemTemplateHeaderTemplate など) のみが含まれます。 次のチュートリアルでは、FormView を使用してレンダリングされたレイアウトをさらに制御する方法について説明します。

プログラミングに満足!

著者について

7 冊の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジに取り組んでいます。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。

特別な感謝

このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は Dan Jagers でした。 今後の MSDN の記事を確認することに関心がありますか? その場合は、 にmitchell@4GuysFromRolla.com行をドロップしてください。