Share via


ラジオ ボタンの GridView 列を追加する (VB)

作成者: Scott Mitchell

PDF のダウンロード

このチュートリアルでは、GridView コントロールにラジオ ボタンの列を追加して、GridView の 1 行を選択するより直感的な方法をユーザーに提供する方法について説明します。

はじめに

GridView コントロールには、多くの組み込み機能が用意されています。 テキスト、画像、ハイパーリンク、ボタンを表示するためのさまざまなフィールドが含まれています。 さらにカスタマイズするためのテンプレートがサポートされています。 マウスを数回クリックするだけで、ボタンを使用して各行を選択できる GridView を作成したり、編集または削除機能を有効にしたりできます。 多数の機能が提供されているにもかかわらず、多くの場合、サポートされていない追加の機能を追加する必要があります。 このチュートリアルと次の 2 つでは、GridView の機能を強化して追加の機能を含める方法について説明します。

このチュートリアルと次のチュートリアルでは、行選択プロセスの強化に重点を置きます。 詳細詳細 ビューで選択可能なマスター GridView を使用したマスター/詳細に関するページで確認したように、[選択] ボタンを含む CommandField を GridView に追加できます。 クリックすると、ポストバックが続き、GridView の SelectedIndex プロパティが、Select ボタンがクリックされた行のインデックスに更新されます。 マスター /詳細 詳細ビューで選択可能なマスター GridView を使用 するチュートリアルでは、この機能を使用して、選択した GridView 行の詳細を表示する方法について説明しました。

[選択] ボタンは多くの状況で機能しますが、他の状況では機能しない場合があります。 ボタンを使用するのではなく、他の 2 つのユーザー インターフェイス要素が一般的に選択に使用されます。ラジオ ボタンとチェック ボックスです。 GridView を拡張して、Select ボタンではなく、各行にラジオ ボタンまたはチェック ボックスが含まれるようにすることができます。 ユーザーが GridView レコードの 1 つのみを選択できるシナリオでは、[選択] ボタンよりもラジオ ボタンが優先される場合があります。 Web ベースの電子メール アプリケーションなど、ユーザーが複数のレコードを選択できる可能性がある状況では、ユーザーが複数のメッセージを選択してチェックボックスを削除する必要がある場合は、[選択] ボタンまたはラジオ ボタンのユーザー インターフェイスからは使用できない機能が提供されます。

このチュートリアルでは、GridView にラジオ ボタンの列を追加する方法について説明します。 このチュートリアルでは、チェックボックスの使用について説明します。

手順 1: GridView Web ページの拡張の作成

GridView の強化を開始してラジオ ボタンの列を含める前に、まず、このチュートリアルと次の 2 つのために必要な ASP.NET ページを Web サイト プロジェクトに作成してみましょう。 まず、 という名前 EnhancedGridViewの新しいフォルダーを追加します。 次に、次の ASP.NET ページをそのフォルダーに追加し、各ページをマスター ページに Site.master 関連付けます。

  • Default.aspx
  • RadioButtonField.aspx
  • CheckBoxField.aspx
  • InsertThroughFooter.aspx

SqlDataSource-Related チュートリアルの ASP.NET ページを追加する

図 1: SqlDataSource-Related チュートリアルの ASP.NET ページを追加する

他のフォルダーと同様に、 Default.aspx フォルダーの EnhancedGridView セクションにチュートリアルが一覧表示されます。 ユーザー コントロールには SectionLevelTutorialListing.ascx この機能があることを思い出してください。 したがって、このユーザー コントロールを に追加するにはDefault.aspx、ソリューション エクスプローラーからページのデザイン ビューにドラッグします。

SectionLevelTutorialListing.ascx ユーザー コントロールを Default.aspx に追加する

図 2: ユーザー コントロールを SectionLevelTutorialListing.ascx に追加する Default.aspx (クリックするとフルサイズの画像が表示されます)

最後に、これら 4 つのページをエントリとしてファイルに Web.sitemap 追加します。 具体的には、SqlDataSource コントロール <siteMapNode>の使用の後に次のマークアップを追加します。

<siteMapNode 
    title="Enhancing the GridView" 
    url="~/EnhancedGridView/Default.aspx" 
    description="Augment the user experience of the GridView control.">
    <siteMapNode 
        url="~/EnhancedGridView/RadioButtonField.aspx" 
        title="Selection via a Radio Button Column" 
        description="Explore how to add a column of radio buttons in the GridView." />
    <siteMapNode 
        url="~/EnhancedGridView/CheckBoxField.aspx" 
        title="Selection via a Checkbox Column" 
        description="Select multiple records in the GridView by using a column of 
            checkboxes." />
    <siteMapNode 
        url="~/EnhancedGridView/InsertThroughFooter.aspx" 
        title="Add New Records through the Footer" 
        description="Learn how to allow users to add new records through the 
            GridView's footer." />
</siteMapNode>

を更新した Web.sitemap後、ブラウザーを使用してチュートリアル Web サイトを表示します。 左側のメニューに、チュートリアルの編集、挿入、削除の項目が含まれるようになりました。

サイト マップに GridView の拡張チュートリアルのエントリが含まれるようになりました

図 3: サイト マップに GridView の拡張チュートリアルのエントリが含まれるようになりました

手順 2: GridView で仕入先を表示する

このチュートリアルでは、米国のサプライヤーを一覧表示する GridView を構築し、各 GridView 行にラジオ ボタンを提供します。 ラジオ ボタンを使用して仕入先を選択した後、ユーザーはボタンをクリックして仕入先の製品を表示できます。 このタスクは簡単に聞こえるかもしれませんが、特に難しい微妙な点がいくつかあります。 これらの機微を掘り下げる前に、まず、サプライヤーを一覧表示する GridView を取得しましょう。

まず、ツールボックスからDesignerに EnhancedGridView GridView をドラッグして、フォルダー内のページを開RadioButtonField.aspxきます。 GridView を IDSuppliers 設定し、スマート タグから新しいデータ ソースを作成することを選択します。 具体的には、 オブジェクトからデータをプルする という名前 SuppliersDataSource の ObjectDataSource を SuppliersBLL 作成します。

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

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

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

図 5: クラスを使用 SuppliersBLL するように ObjectDataSource を構成する (フルサイズの画像を表示するにはクリックします)

米国内のサプライヤーのみを一覧表示するため、[選択 GetSuppliersByCountry(country) ] タブのドロップダウン リストから方法を選択します。

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

図 6: クラスを使用 SuppliersBLL するように ObjectDataSource を構成する (フルサイズの画像を表示するにはクリックします)

[更新] タブで、[(なし)] オプションを選択し、[次へ] をクリックします。

[更新] タブの [データ ソースの構成 - SuppliersDataSource] ウィンドウのスクリーンショット。メソッドのドロップダウン メニューが開いています。メソッド オプション (なし) が選択され、[次へ] ボタンが強調表示されています。

図 7: クラスを使用 SuppliersBLL するように ObjectDataSource を構成する (フルサイズの画像を表示するにはクリックします)

メソッドは GetSuppliersByCountry(country) パラメーターを受け取るので、データ ソースの構成ウィザードによって、そのパラメーターのソースの入力を求められます。 ハードコーディングされた値 (この例では USA) を指定するには、[パラメーター ソース] ドロップダウン リストを [なし] に設定したままにし、テキスト ボックスに既定値を入力します。 [完了] をクリックしてウィザードを終了します。

country パラメーターの既定値として USA を使用する

図 8: パラメーターの既定値 country として USA を使用する (フルサイズの画像を表示するにはクリックします)

ウィザードが完了すると、GridView には各仕入先データ フィールドの BoundField が含まれます。 、City、および BoundFields をCompanyName除くすべてを削除しCountry、BoundFields HeaderText プロパティの名前を CompanyName Supplier に変更します。 その後、GridView および ObjectDataSource 宣言構文は次のようになります。

<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False"
    DataKeyNames="SupplierID" DataSourceID="SuppliersDataSource" 
    EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="CompanyName" HeaderText="Supplier" 
            SortExpression="CompanyName" />
        <asp:BoundField DataField="City" HeaderText="City" 
            SortExpression="City" />
        <asp:BoundField DataField="Country" HeaderText="Country" 
            SortExpression="Country" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server" 
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetSuppliersByCountry" TypeName="SuppliersBLL">
    <SelectParameters>
        <asp:Parameter DefaultValue="USA" Name="country" Type="String" />
    </SelectParameters>
</asp:ObjectDataSource>

このチュートリアルでは、選択した仕入先の製品を仕入先リストと同じページまたは別のページに表示できるようにします。 これに対応するには、2 つのボタン Web コントロールをページに追加します。 私は、この 2 つのボタンの を と にListProducts設定IDしました。これは、いつクリックされるとListProductsポストバックが発生し、選択したサプライヤーの製品が同じページに表示されるという考えですが、クリックされるとSendToProducts、ユーザーは製品を一覧表示する別のページにSendToProductsウィスキーされます。

図 9 は、ブラウザーを Suppliers 使用して表示する場合の GridView コントロールと 2 つのボタン Web コントロールを示しています。

米国のサプライヤーの名前、市区町村、国の情報が記載されている

図 9: 米国のサプライヤーの名前、市区町村、国の情報が一覧表示されている (フルサイズの画像を表示する をクリックします)

手順 3: ラジオ ボタンの列を追加する

この時点で、 Suppliers GridView には 3 つの BoundFields があり、米国内の各サプライヤーの会社名、市区町村、および国が表示されます。 ただし、まだラジオ ボタンの列がありません。 残念ながら、GridView には組み込みの RadioButtonField が含まれていません。それ以外の場合は、グリッドに追加して実行できます。 代わりに、TemplateField を追加し、そのフィールドを構成 ItemTemplate してラジオ ボタンをレンダリングし、GridView 行ごとにラジオ ボタンを作成できます。

最初は、TemplateField の に RadioButton Web コントロールを追加することで、目的のユーザー インターフェイスを ItemTemplate 実装できると想定する場合があります。 これにより、GridView の各行に 1 つのラジオ ボタンが追加されますが、ラジオ ボタンをグループ化することはできないため、相互に排他的ではありません。 つまり、エンド ユーザーは GridView から複数のラジオ ボタンを同時に選択できます。

RadioButton Web コントロールの TemplateField を使用しても、必要な機能は提供されませんが、結果のラジオ ボタンがグループ化されない理由を調べる価値があるため、このアプローチを実装しましょう。 まず、Suppliers GridView に TemplateField を追加し、左端のフィールドにします。 次に、GridView のスマート タグから [テンプレートの編集] リンクをクリックし、RadioButton Web コントロールをツールボックスから TemplateFields ItemTemplate にドラッグします (図 10 を参照)。 RadioButton の ID プロパティを に RowSelector 設定し、 プロパティを GroupNameSuppliersGroup設定します。

ItemTemplate に RadioButton Web コントロールを追加する

図 10: RadioButton Web コントロールを に ItemTemplate 追加します (フルサイズの画像を表示する 場合は、ここをクリックします)

Designerを使用してこれらの追加を行った後、GridView のマークアップは次のようになります。

<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False"
    DataKeyNames="SupplierID" DataSourceID="SuppliersDataSource" 
    EnableViewState="False">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:RadioButton ID="RowSelector" runat="server" 
                    GroupName="SuppliersGroup" />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="CompanyName" HeaderText="Supplier" 
            SortExpression="CompanyName" />
        <asp:BoundField DataField="City" HeaderText="City" 
            SortExpression="City" />
        <asp:BoundField DataField="Country" HeaderText="Country" 
            SortExpression="Country" />
    </Columns>
</asp:GridView>

RadioButton の GroupName プロパティ は、一連のラジオ ボタンをグループ化するために使用されます。 同じ GroupName 値を持つすべての RadioButton コントロールはグループ化されたと見なされます。一度に 1 つのグループから選択できるラジオ ボタンは 1 つだけです。 プロパティは GroupName 、レンダリングされたラジオ ボタンの 属性の値を name 指定します。 ブラウザーは、ラジオ ボタンの属性を name 調べて、ラジオ ボタンのグループ化を決定します。

RadioButton Web コントロールが に ItemTemplate追加された状態で、ブラウザーからこのページにアクセスし、グリッドの行のラジオ ボタンをクリックします。 ラジオ ボタンがグループ化されていないことに注目してください。図 11 に示すように、すべての行を選択できます。

GridView のラジオ ボタンがグループ化されていない

図 11: GridView のラジオ ボタンがグループ化されていません (フルサイズの画像を表示するをクリックします)

ラジオ ボタンがグループ化されない理由は、同じGroupNameプロパティ設定を持っているにもかかわらず、レンダリングされるname属性が異なるためです。 これらの違いを確認するには、ブラウザーからビュー/ソースを実行し、ラジオ ボタンのマークアップを確認します。

<input id="ctl00_MainContent_Suppliers_ctl02_RowSelector" 
    name="ctl00$MainContent$Suppliers$ctl02$SuppliersGroup" 
    type="radio" value="RowSelector" />
<input id="ctl00_MainContent_Suppliers_ctl03_RowSelector" 
    name="ctl00$MainContent$Suppliers$ctl03$SuppliersGroup" 
    type="radio" value="RowSelector" />
<input id="ctl00_MainContent_Suppliers_ctl04_RowSelector" 
    name="ctl00$MainContent$Suppliers$ctl04$SuppliersGroup" 
    type="radio" value="RowSelector" />
<input id="ctl00_MainContent_Suppliers_ctl05_RowSelector" 
    name="ctl00$MainContent$Suppliers$ctl05$SuppliersGroup" 
    type="radio" value="RowSelector" />

属性と id 属性のname両方が、プロパティ ウィンドウで指定された正確な値ではなく、他IDの値の先頭に付加されていることに注意してください。 レンダリングされる属性と name 属性の前面に追加されるid追加IDの値はID、親が s を制御IDGridViewRowするラジオ ボタンの s、GridView sID、Content コントロール、IDおよび Web フォームの ですID。 これらは ID 、GridView でレンダリングされた各 Web コントロールに一意 id の値と name 値が含まれるように追加されます。

レンダリングされる各コントロールは異なる name 必要があります id 。これは、ブラウザーがクライアント側の各コントロールを一意に識別する方法と、ポストバック時に発生したアクションまたは変更を Web サーバーに識別する方法であるためです。 たとえば、RadioButton のチェック状態が変更されるたびに、サーバー側のコードを実行したいとします。 これを実現するには、RadioButton の AutoPostBack プロパティを に True 設定し、イベントのイベント ハンドラーを CheckChanged 作成します。 ただし、すべてのラジオ ボタンのレンダリングされた name 値と id 値が同じ場合、ポストバック時にクリックされた特定の RadioButton を特定できませんでした。

その要点は、RadioButton Web コントロールを使用して GridView にラジオ ボタンの列を作成できないことです。 代わりに、適切なマークアップが各 GridView 行に挿入されるように、むしろ古い手法を使用する必要があります。

注意

RadioButton Web コントロールと同様に、テンプレートに追加されたオプション ボタン HTML コントロールには一意 name の属性が含まれるため、グリッド内のラジオ ボタンはグループ化されません。 HTML コントロールに慣れていない場合は、特に ASP.NET 2.0 では HTML コントロールが使用されることはほとんどないので、このメモは無視してください。 しかし、詳細については、 K. Scott Allen のブログ エントリ 「Web コントロールと HTML コントロール」を参照してください。

リテラル コントロールを使用してラジオ ボタン マークアップを挿入する

GridView 内のすべてのラジオ ボタンを正しくグループ化するには、ラジオ ボタン マークアップ ItemTemplateを に手動で挿入する必要があります。 各ラジオ ボタンには同じ name 属性が必要ですが、一意 id の属性が必要です (クライアント側スクリプトを使用してラジオ ボタンにアクセスする場合)。 ユーザーがラジオ ボタンを選択してページをポストバックすると、ブラウザーは選択したラジオ ボタンの value 属性の値を返します。 そのため、各ラジオ ボタンには一意 value の属性が必要です。 最後に、ポストバック時に、選択されている 1 つのラジオ ボタンに属性を追加 checked する必要があります。それ以外の場合は、ユーザーが選択を行ってポストバックした後、ラジオ ボタンは既定の状態 (すべての未選択) に戻ります。

低レベルのマークアップをテンプレートに挿入するために使用できる方法は 2 つあります。 1 つは、マークアップと、分離コード クラスで定義されている書式設定メソッドの呼び出しを組み合わせて実行することです。 この手法については、 GridView コントロールのチュートリアルの「TemplateFields の使用」で最初に 説明しました。 この場合、次のようになります。

<input type="radio" id='<%# GetUniqueRadioButtonID(...) %>' 
    name='SuppliersGroup' value='<%# GetRadioButtonValue(...) %>' ... />

ここでは、 と GetRadioButtonValue は、GetUniqueRadioButton各ラジオ ボタンの適切な id 属性値とvalue属性値を返す分離コード クラスで定義されたメソッドです。 この方法は、 属性と value 属性をid割り当てるのに適していますが、データバインド構文が実行されるのは、データが GridView に最初にバインドされたときにのみ実行されるため、属性値を指定checkedする必要がある場合は不足します。 したがって、GridView でビュー ステートが有効になっている場合、書式設定メソッドは、ページが最初に読み込まれた場合 (または GridView がデータ ソースに明示的にリバウンドされた場合) にのみ発生するため、属性を設定 checked する関数はポストバックでは呼び出されません。 それはかなり微妙な問題であり、この記事の範囲を少し超えているので、私はこれを残します。 しかし、私はあなたが上記のアプローチを使用して、あなたが行き詰まるまでそれを試してみることをお勧めします。 このような演習では、作業バージョンに近づくことはありませんが、GridView とデータバインドライフサイクルをより深く理解するのに役立ちます。

テンプレートにカスタムの低レベルマークアップを挿入するもう 1 つの方法と、このチュートリアルで使用するアプローチは、 テンプレートに Literal コントロール を追加することです。 次に、GridView の RowCreated または RowDataBound イベント ハンドラーで、Literal コントロールにプログラムでアクセスし、そのプロパティを Text マークアップに設定して出力できます。

まず、TemplateFields ItemTemplateから RadioButton を削除し、リテラル コントロールに置き換えます。 Literal コントロール s ID を に RadioButtonMarkup設定します。

ItemTemplate にリテラル コントロールを追加する

図 12: リテラル コントロールを に追加する ItemTemplate (フルサイズの画像を表示する 場合はクリックします)

次に、GridView のイベントのイベント ハンドラーを RowCreated 作成します。 このイベントは RowCreated 、データが GridView にリバウンドされているかどうかに関係なく、追加されたすべての行に対して 1 回発生します。 つまり、ビュー ステートからデータが再読み込みされてもポストバック時でもイベントは発生し、 RowCreated これは (データがデータ Web コントロールに明示的にバインドされている場合にのみ発生する) の代わりに RowDataBound 使用している理由です。

このイベント ハンドラーでは、データ行を処理する場合にのみ続行します。 データ行ごとに、プログラムによって Literal コントロールを RadioButtonMarkup 参照し、その Text プロパティを出力するマークアップに設定します。 次のコードに示すように、出力されるマークアップは、属性が にSuppliersGroup設定されているラジオ ボタンを作成します。このidオプション ボタンnameの属性は にRowSelectorX設定されています。ここで、X は GridView 行のインデックスであり、そのvalue属性は GridView 行のインデックスに設定されます。

Protected Sub Suppliers_RowCreated(sender As Object, e As GridViewRowEventArgs) _
    Handles Suppliers.RowCreated
    
    If e.Row.RowType = DataControlRowType.DataRow Then
        ' Grab a reference to the Literal control
        Dim output As Literal = _
            CType(e.Row.FindControl("RadioButtonMarkup"), Literal)
        ' Output the markup except for the "checked" attribute
        output.Text = String.Format( _
            "<input type="radio" name="SuppliersGroup" " & _
            "id="RowSelector{0}" value="{0}" />", e.Row.RowIndex)
    End If
End Sub

GridView 行が選択され、ポストバックが発生すると、選択した仕入先の に SupplierID 関心があります。 したがって、各ラジオ ボタンの値は実際の (GridView 行のインデックスではなく) である SupplierID 必要があると考える場合があります。 これは特定の状況で機能する可能性があります。しかし、 を盲目的に受け入れて処理することはセキュリティ 上の SupplierIDリスクになります。 たとえば、GridView には、米国のサプライヤーのみが一覧表示されます。 しかし、 がラジオ ボタンから直接渡された場合 SupplierID 、いたずらなユーザーがポストバック時に返される値を操作するのを SupplierID 止めるには何が必要ですか? 行インデックスを としてvalue使用し、コレクションからDataKeysポストバック時に SupplierID を取得することで、ユーザーが GridView 行のいずれかにSupplierID関連付けられているいずれかの値のみを使用していることを確認できます。

このイベント ハンドラー コードを追加した後、ブラウザーでページをテストするには 1 分かかります。 最初に、グリッド内の 1 つのラジオ ボタンのみを一度に選択できることに注意してください。 ただし、ラジオ ボタンを選択し、いずれかのボタンをクリックすると、ポストバックが発生し、ラジオ ボタンはすべて初期状態に戻ります (つまり、ポストバックでは、選択したラジオ ボタンは選択されなくなります)。 これを修正するには、ポストバックから送信された選択したラジオ ボタン インデックスを検査し、行インデックスの一致する出力マークアップに 属性を追加checked="checked"するように、イベント ハンドラーを拡張RowCreatedする必要があります。

ポストバックが発生すると、ブラウザーは選択したラジオ ボタンの と value を返nameします。 値は、 を使用して Request.Form("name")プログラムで取得できます。 プロパティはRequest.Form、フォーム変数を表す を提供NameValueCollectionします。 フォーム変数は、Web ページ内のフォーム フィールドの名前と値であり、ポストバックが発生するたびに Web ブラウザーによって返送されます。 GridView のラジオ ボタンのレンダリングされた name 属性は であるため、 SuppliersGroupWeb ページがポストバックされると、ブラウザーは (他のフォーム フィールドと共に) Web サーバーに送 SuppliersGroup=valueOfSelectedRadioButton り返されます。 この情報は、 を使用して Request.Form("SuppliersGroup")プロパティからRequest.Formアクセスできます。

選択したラジオ ボタン インデックスは、イベント ハンドラーだけでなく、Button Web コントロールのイベント ハンドラーでもRowCreatedClick決定する必要があるため、オプション ボタンが選択されていない場合は を返す分離コード クラスにプロパティを追加SuppliersSelectedIndexし、いずれかのラジオ ボタンが選択されている場合は選択したインデックスを返-1します。

Private ReadOnly Property SuppliersSelectedIndex() As Integer
    Get
        If String.IsNullOrEmpty(Request.Form("SuppliersGroup")) Then
            Return -1
        Else
            Return Convert.ToInt32(Request.Form("SuppliersGroup"))
        End If
    End Get
End Property

このプロパティを追加すると、 と等しい場合SuppliersSelectedIndexchecked="checked"イベント ハンドラーにマークアップをRowCreatede.Row.RowIndex追加することがわかります。 イベント ハンドラーを更新して、次のロジックを含めます。

Protected Sub Suppliers_RowCreated(sender As Object, e As GridViewRowEventArgs) _
    Handles Suppliers.RowCreated
    
    If e.Row.RowType = DataControlRowType.DataRow Then
        ' Grab a reference to the Literal control
        Dim output As Literal = _
            CType(e.Row.FindControl("RadioButtonMarkup"), Literal)
        ' Output the markup except for the "checked" attribute
        output.Text = String.Format( _
            "<input type="radio" name="SuppliersGroup" " & _
            "id="RowSelector{0}" value="{0}"", e.Row.RowIndex)
        ' See if we need to add the "checked" attribute
        If SuppliersSelectedIndex = e.Row.RowIndex Then
            output.Text &= " checked="checked""
        End If
        ' Add the closing tag
        output.Text &= " />"
    End If
End Sub

この変更により、選択したラジオ ボタンはポストバック後も選択されたままになります。 これで、どのラジオ ボタンを選択するかを指定できるようになりました。この動作を変更して、ページが最初にアクセスされたときに、最初の GridView 行のラジオ ボタンが選択されるようにすることができます (既定では、現在の動作であるラジオ ボタンが選択されていません)。 既定で最初のラジオ ボタンを選択するには、 ステートメントを If SuppliersSelectedIndex = e.Row.RowIndex ThenIf SuppliersSelectedIndex = e.Row.RowIndex OrElse (Not Page.IsPostBack AndAlso e.Row.RowIndex = 0) Thenのように変更します。

この時点で、グループ化されたラジオ ボタンの列を GridView に追加しました。これにより、1 つの GridView 行を選択し、ポストバック全体で記憶できます。 次の手順では、選択したサプライヤーから提供された製品を表示します。 手順 4 では、ユーザーを別のページにリダイレクトし、選択した SupplierIDに沿って を送信する方法について説明します。 手順 5 では、選択した仕入先の製品を同じページの GridView に表示する方法について説明します。

注意

TemplateField (この長い手順 3 の焦点) を使用するのではなく、適切なユーザー インターフェイスと機能をレンダリングするカスタム DataControlField クラスを作成できます。 クラスはDataControlField、BoundField、CheckBoxField、TemplateField、およびその他の組み込みの GridView フィールドと DetailsView フィールドの派生元となる基本クラスです。 カスタム DataControlField クラスを作成すると、宣言構文を使用するだけでラジオ ボタンの列を追加でき、他の Web ページや他の Web アプリケーションでの機能のレプリケートも大幅に容易になります。

ただし、ASP.NET でカスタムコンパイルされたコントロールを作成したことがある場合は、かなりの量の脚作業が必要であり、慎重に処理する必要がある控えめさとエッジ ケースのホストを備えています。 したがって、ここではラジオ ボタンの列をカスタム DataControlField クラスとして実装することを見越し、TemplateField オプションを使用します。 おそらく、今後のチュートリアルでカスタム DataControlField クラスの作成、使用、デプロイについて調べる機会があります。

手順 4: 選択した仕入先の製品を別のページに表示する

ユーザーが GridView 行を選択したら、選択した仕入先の製品を表示する必要があります。 状況によっては、これらの製品を別のページに表示したい場合もあれば、同じページで表示したい場合もあります。 まず、製品を別のページに表示する方法を調べてみましょう。手順 5 では、GridView を に追加して RadioButtonField.aspx 、選択した仕入先の製品を表示します。

現在、ページListProductsSendToProductsには と の 2 つのボタン Web コントロールがあります。 ボタンが SendToProducts クリックされると、ユーザーを に ~/Filtering/ProductsForSupplierDetails.aspx送信します。 このページは、2 ページにわたるマスター/詳細フィルター処理のチュートリアルで作成され、 という名前SupplierIDの querystring フィールドを介して渡される仕入先SupplierIDの製品が表示されます。

この機能を提供するには、Button イベントClickのイベント ハンドラーをSendToProducts作成します。 手順 3 では、 プロパティを SuppliersSelectedIndex 追加しました。このプロパティは、ラジオ ボタンが選択されている行のインデックスを返します。 対応する SupplierID は GridView のDataKeysコレクションから取得でき、ユーザーは を使用して Response.Redirect("url")~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID送信できます。

Protected Sub SendToProducts_Click(sender As Object, e As EventArgs) _
    Handles SendToProducts.Click
    
    ' Send the user to ~/Filtering/ProductsForSupplierDetails.aspx
    Dim supplierID As Integer = _
        Convert.ToInt32(Suppliers.DataKeys(SuppliersSelectedIndex).Value)
    Response.Redirect( _
        "~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=" & _
        supplierID)
End Sub

このコードは、GridView からラジオ ボタンの 1 つが選択されている限り、素晴らしく機能します。 最初に GridView にラジオ ボタンが選択されておらず、ユーザーがボタンをSendToProductsクリックすると、 がになり、 SuppliersSelectedIndex-1コレクションのDataKeysインデックス範囲外であるため-1に例外がスローされます。 ただし、GridView の最初のラジオ ボタンが最初に選択されるように、手順 3 で説明したようにイベント ハンドラーを更新 RowCreated することにした場合は、これは問題ではありません。

-1値にSuppliersSelectedIndex対応するには、GridView の上のページに Label Web コントロールを追加します。 プロパティを IDChooseSupplierMsg設定し、そのCssClassプロパティを に、プロパティを EnableViewStateVisibleWarning、プロパティを にFalse設定し、そのTextプロパティをグリッドから仕入先を選択してください。 CSS クラス Warning は、赤、斜体、太字、大きなフォントでテキストを表示し、 で Styles.css定義されます。 プロパティと Visible プロパティを EnableViewStateFalse設定すると、コントロールの Visible プロパティがプログラムによって に設定Trueされているポストバックのみを除き、Label はレンダリングされません。

GridView の上にラベル Web コントロールを追加する

図 13: GridView の上にラベル Web コントロールを追加する (クリックするとフルサイズの画像が表示されます)

次に Click 、 が 0 未満の場合は Label を ChooseSupplierMsg 表示するようにイベント ハンドラーを拡張し、それ以外の場合 SuppliersSelectedIndex はユーザーを ~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID リダイレクトします。

Protected Sub SendToProducts_Click(sender As Object, e As EventArgs) _
    Handles SendToProducts.Click
    
    ' make sure one of the radio buttons has been selected
    If SuppliersSelectedIndex < 0 Then
        ChooseSupplierMsg.Visible = True
    Else
        ' Send the user to ~/Filtering/ProductsForSupplierDetails.aspx
        Dim supplierID As Integer = _
            Convert.ToInt32(Suppliers.DataKeys(SuppliersSelectedIndex).Value)
        Response.Redirect( _
            "~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=" & _
            supplierID)
    End If
End Sub

ブラウザーでページにアクセスし、ボタンを SendToProducts クリックしてから GridView からサプライヤーを選択します。 図 14 に示すように、ラベルが ChooseSupplierMsg 表示されます。 次に、仕入先を選択し、ボタンを SendToProducts クリックします。 これにより、選択したサプライヤーから提供された製品が一覧表示されるページが表示されます。 図 15 は、 ProductsForSupplierDetails.aspx Bigfoot ビール醸造所のサプライヤーが選択されたページを示しています。

仕入先が選択されていない場合は、ChooseSupplierMsg ラベルが表示されます

図 14: ChooseSupplierMsg 仕入先が選択されていない場合、ラベルが表示されます (クリックするとフルサイズの画像が表示されます)

選択した仕入先の製品がProductsForSupplierDetails.aspxに表示される

図 15: 選択した仕入先の製品が に ProductsForSupplierDetails.aspx 表示されている (フルサイズの画像を表示する をクリックします)

手順 5: 選択した仕入先の製品を同じページに表示する

手順 4 では、ユーザーを別の Web ページに送信して、選択したサプライヤーの製品を表示する方法を確認しました。 または、選択した仕入先の製品を同じページに表示することもできます。 これを説明するために、選択したサプライヤーの製品を表示するために、別の GridView を に RadioButtonField.aspx 追加します。

この製品の GridView は、仕入先が選択された後にのみ表示する必要があるため、GridView の下に Panel Web コントロールを Suppliers 追加し、その ID を に ProductsBySupplierPanel 設定し、その Visible プロパティを に False設定します。 パネル内で、選択した仕入先の [製品] というテキストを追加し、その後に という名前 ProductsBySupplierの GridView を追加します。 GridView のスマート タグから、 という名前 ProductsBySupplierDataSourceの新しい ObjectDataSource にバインドすることを選択します。

ProductsBySupplier GridView を新しい ObjectDataSource にバインドする

図 16: GridView を ProductsBySupplier 新しい ObjectDataSource にバインドする (フルサイズの画像を表示する 場合はクリックします)

次に、 クラスを使用するように ObjectDataSource を ProductsBLL 構成します。 選択したサプライヤーによって提供される製品のみを取得するため、ObjectDataSource が メソッドを呼び出してデータを GetProductsBySupplierID(supplierID) 取得するように指定します。 [更新]、[挿入]、および [削除] タブのドロップダウン リストから [(なし)] を選択します。

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

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

UPDATE、INSERT、DELETE の各タブで、Drop-Down Lists を (なし) に設定します

図 18: UPDATE、INSERT、DELETE タブの Drop-Down Lists を (なし) に設定します (フルサイズの画像を表示する場合はクリックします)

SELECT、UPDATE、INSERT、DELETE の各タブを構成したら、[次へ] をクリックします。 メソッドは GetProductsBySupplierID(supplierID) 入力パラメーターを必要とするため、データ ソースの作成ウィザードでは、パラメーターの値のソースを指定するように求められます。

ここでは、パラメーターの値のソースを指定する際に、いくつかのオプションがあります。 既定の Parameter オブジェクトを使用し、ObjectDataSource Selecting のイベント ハンドラーの Parameter プロパティDefaultValueにプロパティのSuppliersSelectedIndex値をプログラムで割り当てることができます。 ObjectDataSource のパラメーターにプログラムで値を割り当てる方法については、プログラムによる ObjectDataSource のパラメーター値の設定に関するチュートリアルを参照してください。

または、ControlParameter を使用し、GridView の SelectedValue プロパティSuppliers参照することもできます (図 19 を参照)。 GridView の SelectedValue プロパティは、 プロパティに DataKey 対応する値を SelectedIndex 返します。 このオプションを機能させるには、ボタンがクリックされたときに GridView の SelectedIndex プロパティを選択した行にプログラムで設定する ListProducts 必要があります。 追加の利点として、 をSelectedIndex設定すると、選択したレコードはテーマ (黄色の背景) でDataWebControls定義された を受け取りますSelectedRowStyle

ControlParameter を使用して GridView の SelectedValue をパラメーター ソースとして指定する

図 19: ControlParameter を使用して GridView の SelectedValue をパラメーター ソースとして指定する (フルサイズの画像を表示する 場合はクリックします)

ウィザードが完了すると、Visual Studio によって製品のデータ フィールドのフィールドが自動的に追加されます。 、CategoryNameProductNameおよび UnitPrice BoundFields を除くすべてを削除し、プロパティを HeaderText Product、Category、Price に変更します。 BoundField を UnitPrice 構成して、その値が通貨として書式設定されるようにします。 これらの変更を行った後、Panel、GridView、ObjectDataSource の宣言型マークアップは次のようになります。

<asp:Panel runat="server" ID="ProductsBySupplierPanel" Visible="False">
    <h3>
        Products for the Selected Supplier</h3>
    <p>
        <asp:GridView ID="ProductsBySupplier" runat="server" 
            AutoGenerateColumns="False" DataKeyNames="ProductID"
            DataSourceID="ProductsBySupplierDataSource" EnableViewState="False">
            <Columns>
                <asp:BoundField DataField="ProductName" HeaderText="Product" 
                    SortExpression="ProductName" />
                <asp:BoundField DataField="CategoryName" HeaderText="Category" 
                    ReadOnly="True" SortExpression="CategoryName" />
                <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}" 
                    HeaderText="Price" HtmlEncode="False" 
                    SortExpression="UnitPrice" />
            </Columns>
        </asp:GridView>
        <asp:ObjectDataSource ID="ProductsBySupplierDataSource" runat="server" 
            OldValuesParameterFormatString="original_{0}"
            SelectMethod="GetProductsBySupplierID" TypeName="ProductsBLL">
            <SelectParameters>
                <asp:ControlParameter ControlID="Suppliers" Name="supplierID" 
                    PropertyName="SelectedValue" Type="Int32" />
            </SelectParameters>
        </asp:ObjectDataSource>
    </p>
</asp:Panel>

この演習を完了するには、ボタンがクリックされたときに GridView の SelectedIndex プロパティを にSelectedSuppliersIndex設定しProductsBySupplierPanel、Panel の Visible プロパティを に設定するTrueListProducts必要があります。 これを実現するには、Button Web コントロールの Click イベントのイベント ハンドラーをListProducts作成し、次のコードを追加します。

Protected Sub ListProducts_Click(sender As Object, e As EventArgs) _
    Handles ListProducts.Click
    
    ' make sure one of the radio buttons has been selected
    If SuppliersSelectedIndex < 0 Then
        ChooseSupplierMsg.Visible = True
        ProductsBySupplierPanel.Visible = False
    Else
        ' Set the GridView's SelectedIndex
        Suppliers.SelectedIndex = SuppliersSelectedIndex
        ' Show the ProductsBySupplierPanel panel
        ProductsBySupplierPanel.Visible = True
    End If
End Sub

GridView から仕入先が選択されていない場合は、 ChooseSupplierMsg ラベルが表示され、パネルは ProductsBySupplierPanel 非表示になります。 それ以外の場合、仕入先が選択されている場合は、 ProductsBySupplierPanel が表示され、GridView の SelectedIndex プロパティが更新されます。

図 20 は、Bigfoot のビール醸造所サプライヤーが選択され、[ページに製品を表示] ボタンがクリックされた後の結果を示しています。

ビッグフット醸造所が提供する製品は、同じページに記載されています

図 20: Bigfoot の醸造所から提供される製品が同じページに一覧表示されている (フルサイズの画像を表示する をクリックします)

まとめ

詳細詳細ビューを 使用した選択可能なマスター グリッド ビューの使用 に関するチュートリアルで説明したように、プロパティが に設定されている CommandField ShowSelectButton を使用して、GridView からレコードを True選択できます。 ただし、CommandField では、ボタンが通常のプッシュ ボタン、リンク、または画像として表示されます。 別の行選択ユーザー インターフェイスは、各 GridView 行にラジオ ボタンまたはチェック ボックスを提供することです。 このチュートリアルでは、ラジオ ボタンの列を追加する方法を調べました。

残念ながら、ラジオ ボタンの列を追加することは、予想ほど簡単でも簡単でもないです。 ボタンのクリック時に追加できる組み込みの RadioButtonField はなく、TemplateField 内で RadioButton Web コントロールを使用すると、独自の一連の問題が発生します。 最後に、このようなインターフェイスを提供するには、カスタム DataControlField クラスを作成するか、イベント中に適切な HTML を TemplateField に挿入する RowCreated 必要があります。

ラジオ ボタンの列を追加する方法について説明しました。チェックボックスの列を追加することに注意してください。 チェック ボックスの列を使用すると、ユーザーは 1 つ以上の GridView 行を選択し、選択したすべての行に対して何らかの操作を実行できます (Web ベースの電子メール クライアントから一連のメールを選択し、選択したすべてのメールを削除することを選択するなど)。 次のチュートリアルでは、このような列を追加する方法について説明します。

プログラミングに満足!

著者について

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

特別な感謝

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