2 つの DropDownList でマスター/詳細をフィルター処理する (VB)

作成者: Scott Mitchell

PDF のダウンロード

このチュートリアルでは、マスター/詳細リレーションシップを展開して 3 番目のレイヤーを追加します。2 つの DropDownList コントロールを使用して、目的の親レコードと祖父母レコードを選択します。

はじめに

前の チュートリアル では、カテゴリが設定された 1 つの DropDownList と、選択したカテゴリに属する製品を表示する GridView を使用して、単純なマスター/詳細レポートを表示する方法を確認しました。 このレポート パターンは、一対多リレーションシップを持ち、複数の一対多リレーションシップを含むシナリオで機能するように簡単に拡張できるレコードを表示する場合に適しています。 たとえば、注文入力システムには、顧客、注文、および注文明細に対応するテーブルがあります。 特定の顧客が複数の注文を持ち、各注文が複数の品目で構成される場合があります。 このようなデータは、2 つの DropDownList と GridView を使用してユーザーに表示できます。 1 つ目の DropDownList には、データベース内の各顧客のリスト アイテムがあり、2 番目の DropDownList の内容は、選択した顧客によって注文されます。 GridView では、選択した注文の品目が一覧表示されます。

Northwind データベースには、標準の顧客/注文/注文の詳細情報が CustomersOrders、および Order Details テーブルに含まれていますが、これらのテーブルはアーキテクチャではキャプチャされません。 それでも、2 つの依存する DropDownList の使用を示すことができます。 最初の DropDownList にはカテゴリが一覧表示され、2 番目の DropDownList には選択したカテゴリに属する製品が一覧表示されます。 選択した製品の詳細が DetailsView に一覧表示されます。

手順 1: カテゴリ DropDownList の作成と設定

最初の目標は、カテゴリを一覧表示する DropDownList を追加することです。 これらの手順は、前のチュートリアルで詳しく調べましたが、ここでは完全のためにまとめられています。

フォルダー内のページをMasterDetailsDetails.aspxFiltering開き、ページに DropDownList を追加し、そのIDプロパティを にCategories設定し、スマート タグの [データ ソースの構成] リンクをクリックします。 データ ソース構成ウィザードで、新しいデータ ソースを追加することを選択します。

DropDownList の新しいデータ ソースを追加する

図 1: DropDownList の新しいデータ ソースを追加する (フルサイズの画像を表示するをクリックします)

新しいデータ ソースは、当然ながら ObjectDataSource である必要があります。 この新しい ObjectDataSource にCategoriesDataSource名前を付け、オブジェクトの GetCategories() メソッドをCategoriesBLL呼び出すようにします。

CategoriesBLL クラスの使用を選択する

図 2: クラスの使用を選択する CategoriesBLL (クリックするとフルサイズの画像が表示されます)

GetCategories() メソッドを使用するように ObjectDataSource を構成する

図 3: メソッドを使用 GetCategories() するように ObjectDataSource を構成する (フルサイズの画像を表示するにはクリックします)

ObjectDataSource を構成した後も、DropDownList に表示 Categories するデータ ソース フィールドと、リスト アイテムの値として構成するデータ ソース フィールドを指定する必要があります。 フィールドを CategoryName 表示として設定し、 CategoryID 各リスト アイテムの値として設定します。

DropDownList に CategoryName フィールドを表示し、値として CategoryID を使用する

図 4: DropDownList にフィールドを CategoryName 表示し、値として使用 CategoryID する (フルサイズの画像を表示するにはクリックします)

この時点で、テーブルのレコードが設定された DropDownList コントロール (Categories) があります Categories 。 ユーザーが DropDownList から新しいカテゴリを選択すると、手順 2 で作成する製品の DropDownList を更新するためにポストバックが発生します。 そのため、DropDownList のスマート タグから [自動ポストバックを有効にする] オプションをcategoriesチェックします。

カテゴリ DropDownList に対して AutoPostBack を有効にする

図 5: DropDownList の自動ポストバックを Categories 有効にする (フルサイズの画像を表示するをクリックします)

手順 2: 選択したカテゴリの製品を 2 番目の DropDownList に表示する

DropDownList が Categories 完了したら、次の手順では、選択したカテゴリに属する製品の DropDownList を表示します。 これを実現するには、 という名前 ProductsByCategoryのページに別の DropDownList を追加します。 DropDownList と同様にCategories、 という名前ProductsByCategoryDataSourceの DropDownList のProductsByCategory新しい ObjectDataSource を作成します。

ProductsByCategory DropDownList の新しいデータ ソースを追加する

図 6: DropDownList の新しいデータ ソースを ProductsByCategory 追加する (フルサイズの画像を表示するをクリックします)

ProductsByCategoryDataSource という名前の新しい ObjectDataSource を作成する

図 7: 名前付きの ProductsByCategoryDataSource 新しい ObjectDataSource を作成する (フルサイズの画像を表示する場合はクリックします)

ProductsByCategory DropDownList では、選択したカテゴリに属する製品のみを表示する必要があるため、ObjectDataSource で オブジェクトから メソッドをGetProductsByCategoryID(categoryID)ProductsBLL呼び出します。

[データ ソースの構成 - productsByCategoryDataSource] ウィンドウのスクリーンショット。ProductsBLL が選択され、[次へ] ボタンが強調表示されているビジネス オブジェクトドロップダウン メニューが表示されています。

図 8: クラスの使用を選択する ProductsBLL (クリックするとフルサイズの画像が表示されます)

GetProductsByCategoryID(categoryID) メソッドを使用するように ObjectDataSource を構成する

図 9: メソッドを使用 GetProductsByCategoryID(categoryID) するように ObjectDataSource を構成する (フルサイズの画像を表示するにはクリックします)

ウィザードの最後の手順では、 パラメーターの値を指定する categoryID 必要があります。 このパラメーターを DropDownList から選択したアイテムに Categories 割り当てます。

Category DROPDownList から categoryID パラメーター値をプルする

図 10: DropDownList からパラメーター値をCategoriesプルcategoryIDする (フルサイズの画像を表示する をクリックします)

ObjectDataSource が構成されている場合、残っているのは、DropDownList のアイテムの表示と値に使用されるデータ ソース フィールドを指定することです。 フィールドを ProductName 表示し、フィールドを ProductID 値として使用します。

DropDownList の ListItems の Text プロパティと Value プロパティに使用するデータ ソース フィールドを指定する

図 11: DropDownList ListItemTextValue の および プロパティに使用されるデータ ソース フィールドを指定する (フルサイズの画像を表示する をクリックします)

ObjectDataSource と ProductsByCategory DropDownList を構成すると、ページに 2 つの DropDownList が表示されます。1 つ目はすべてのカテゴリが一覧表示され、2 つ目は選択したカテゴリに属する製品を一覧表示します。 ユーザーが最初の DropDownList から新しいカテゴリを選択すると、ポストバックが実行され、2 番目の DropDownList がリバウンドされ、新しく選択したカテゴリに属する製品が表示されます。 図 12 と図 13 は、ブラウザーを使用して表示した場合の動作を示 MasterDetailsDetails.aspx しています。

最初にページにアクセスすると、[飲料] カテゴリが選択されます

図 12: 最初にページにアクセスするときに、[飲料] カテゴリが選択されています (フルサイズの画像を表示する 場合はクリックします)

別のカテゴリを選択すると、新しいカテゴリの製品が表示されます

図 13: 別のカテゴリを選択すると、新しいカテゴリの製品が表示されます (クリックするとフルサイズの画像が表示されます)

現在、 productsByCategory DropDownList が変更された場合、ポストバックは発生 しません 。 ただし、選択した製品の詳細を表示する DetailsView を追加すると、ポストバックが発生します (手順 3)。 そのため、DropDownList のスマート タグから [自動ポストバックを有効にする] チェック ボックスをproductsByCategoryチェックします。

productsByCategory DropDownList の自動ポストバック機能を有効にする

図 14: DropDownList の自動ポストバック機能を productsByCategory 有効にする (フルサイズの画像を表示する をクリックします)

手順 3: DetailsView を使用して選択した製品の詳細を表示する

最後の手順では、選択した製品の詳細を DetailsView に表示します。 これを実現するには、DetailsView をページに追加し、そのプロパティを IDProductDetails設定し、新しい ObjectDataSource を作成します。 パラメーターの値として DropDownList の選択した値を ProductsBLL 使用して、クラスの GetProductByProductID(productID) メソッドからデータを ProductsByCategory プルするように、この ObjectDataSource を productID 構成します。

ビジネス オブジェクトドロップダウン メニューが開いている [データ ソースの構成 - productsByCategoryDataSource] ウィンドウのスクリーンショット。ProductsBLL が選択され、[次へ] ボタンが強調表示されています。

図 15: クラスの使用を選択する ProductsBLL (クリックするとフルサイズの画像が表示されます)

GetProductByProductID(productID) メソッドを使用するように ObjectDataSource を構成する

図 16: メソッドを使用 GetProductByProductID(productID) するように ObjectDataSource を構成する (フルサイズの画像を表示するにはクリックします)

ProductsByCategory DropDownList から productID パラメーター値をプルする

図 17: DropDownList からパラメーター値をProductsByCategoryプルproductIDします (フルサイズの画像を表示する 場合はクリックします)

DetailsView で使用可能なフィールド ProductDetails を表示することを選択できます。 、、および CategoryID の各フィールドをProductIDSupplierID削除し、残りのフィールドを並べ替えて書式設定しました。 さらに、DetailsView の Height プロパティと Width プロパティをクリアして、指定したサイズに制限するのではなく、データを最適に表示するために必要な幅まで DetailsView を拡張できるようにしました。 完全なマークアップを次に示します。

<asp:DetailsView ID="ProductDetails" runat="server"
    AutoGenerateRows="False" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" 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"
           DataFormatString="{0:c}" HeaderText="Price"
            HtmlEncode="False" SortExpression="UnitPrice" />
        <asp:BoundField DataField="UnitsInStock"
            HeaderText="UnitsInStock"
            SortExpression="Units In Stock" />
        <asp:BoundField DataField="UnitsOnOrder"
            HeaderText="UnitsOnOrder"
            SortExpression="Units On Order" />
        <asp:BoundField DataField="ReorderLevel"
            HeaderText="ReorderLevel" SortExpression="Reorder Level" />
        <asp:CheckBoxField DataField="Discontinued"
            HeaderText="Discontinued" SortExpression="Discontinued" />
    </Fields>
</asp:DetailsView>

少し時間を取って、ブラウザーでページを試してみてください MasterDetailsDetails.aspx 。 一見すると、すべてが必要に応じて動作しているように見えるかもしれませんが、微妙な問題があります。 新しいカテゴリを選択すると、 ProductsByCategory 選択したカテゴリの製品が含まれるよう DropDownList が更新されますが ProductDetails 、DetailsView では以前の製品情報が引き続き表示されます。 選択したカテゴリに別の製品を選択すると、DetailsView が更新されます。 さらに、十分に十分にテストすると、新しいカテゴリ (DropDownList から [飲み物 Categories ] を選択し、次に [Condiments]、[菓子] など) を選択し続けると、DetailsView ProductDetails が更新されることがわかります。

この問題を解決するために、具体的な例を見てみましょう。 最初にページにアクセスすると、[飲料] カテゴリが選択され、関連する製品が DropDownList に ProductsByCategory 読み込まれます。 Chai は選択した製品であり、その詳細は図 18 に示すように DetailsView に表示されます ProductDetails

選択した製品の詳細が DetailsView に表示される

図 18: 選択した製品の詳細が DetailsView に表示される (フルサイズの画像を表示する場合をクリックします)

カテゴリの選択を飲料から Condiments に変更すると、ポストバックが発生し ProductsByCategory 、それに応じて DropDownList が更新されますが、DetailsView には Chai の詳細が引き続き表示されます。

以前に選択した製品の詳細は引き続き表示されます

図 19: 以前に選択した製品の詳細はまだ表示されます (フルサイズの画像を表示する場合はクリックします)

リストから新しい製品を選択すると、DetailsView が期待どおりに更新されます。 製品を変更した後に新しいカテゴリを選択した場合、DetailsView は再び更新されません。 ただし、新しい製品を選択する代わりに新しいカテゴリを選択した場合、DetailsView は更新されます。 世界で何が起こっているのですか?

問題は、ページのライフサイクルにおけるタイミングの問題です。 ページが要求されるたびに、レンダリングとしていくつかの手順を実行します。 これらの手順の 1 つで、ObjectDataSource コントロールチェック、値SelectParametersのいずれかが変更されているかどうかを確認します。 その場合、ObjectDataSource にバインドされたデータ Web コントロールは、表示を更新する必要があることを認識します。 たとえば、新しいカテゴリが選択されている場合、 ProductsByCategoryDataSource ObjectDataSource は、そのパラメーター値が変更されたことを検出し ProductsByCategory 、DropDownList 自体を再バインドして、選択したカテゴリの製品を取得します。

この状況で発生する問題は、変更されたパラメーターに対して ObjectDataSources がチェックページ ライフサイクルのポイントが、関連付けられているデータ Web コントロールの再バインドの前に発生することです。 したがって、新しいカテゴリを選択すると、 ProductsByCategoryDataSource ObjectDataSource はパラメーターの値の変更を検出します。 ただし、DetailsView で ProductDetails 使用される ObjectDataSource では、DropDownList がまだリバウンドされていないため ProductsByCategory 、このような変更は記録されません。 ライフサイクルの後半で、 ProductsByCategory DropDownList は ObjectDataSource に再バインドし、新しく選択したカテゴリの製品を取得します。 ProductsByCategory DropDownList の値が変更されている間、ProductDetailsDetailsView の ObjectDataSource は既にパラメーター値チェックを実行しているため、DetailsView には以前の結果が表示されます。 この相互作用を図 20 に示します。

ProductDetails DetailsView の ObjectDataSource が変更をチェックした後の ProductsByCategory DropDownList 値の変更

図 20: ProductsByCategory DetailsView の ObjectDataSource が変更を確認した後 ProductDetails の DropDownList 値の変更 (フルサイズの画像を表示する場合をクリックします)

これを解決するには、DropDownList がバインドされた後に ProductDetails DetailsView を明示的に再バインドする ProductsByCategory 必要があります。 これを実現するには、DropDownList のDataBind()イベントが発生したときに ProductsByCategory DetailsView の DataBound メソッドを呼び出ProductDetailsします。 ページの分離コード クラスに MasterDetailsDetails.aspx 次のイベント ハンドラー コードを追加します (イベント ハンドラーを追加する方法については、「ObjectDataSource のパラメーター値をプログラムで設定する」を参照してください)。

Protected Sub ProductsByCategory_DataBound(sender As Object, e As EventArgs) _
    Handles ProductsByCategory.DataBound
        ProductDetails.DataBind()
End Sub

DetailsView DataBind() のメソッドに対するこのProductDetails明示的な呼び出しが追加されると、チュートリアルは期待どおりに動作します。 図 21 は、これが以前の問題をどのように改善したかを示しています。

ProductDetails DetailsView は、ProductsByCategory DropDownList の DataBound イベントが発生したときに明示的に更新されます

図 21: ProductDetails DropDownList のイベントが発生したときに ProductsByCategory DetailsView が明示的に更新される (フルサイズのDataBound画像を表示する場合をクリックします)

まとめ

DropDownList は、マスター レコードと詳細レコードの間に一対多のリレーションシップがあるマスター/詳細レポートの理想的なユーザー インターフェイス要素として機能します。 前のチュートリアルでは、1 つの DropDownList を使用して、選択したカテゴリによって表示される製品をフィルター処理する方法について説明しました。 このチュートリアルでは、製品の GridView を DropDownList に置き換え、DetailsView を使用して選択した製品の詳細を表示しました。 このチュートリアルで説明する概念は、顧客、注文、注文項目など、複数の一対多リレーションシップを含むデータ モデルに簡単に拡張できます。 一般に、一対多リレーションシップの "1" エンティティごとに常に DropDownList を追加できます。

プログラミングに満足!

著者について

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

特別な感謝

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