Share via


GridView にボタンを追加し、応答する (C#)

作成者: Scott Mitchell

PDF のダウンロード

このチュートリアルでは、テンプレートと GridView コントロールまたは DetailsView コントロールのフィールドの両方にカスタム ボタンを追加する方法について説明します。 特に、ユーザーがサプライヤーをページングできるようにする FormView を持つインターフェイスを構築します。

はじめに

多くのレポート シナリオでは、レポート データへの読み取り専用アクセスが含まれますが、レポートに表示されるデータに基づいてアクションを実行する機能が含まれることは珍しくありません。 通常、これには、ボタン、LinkButton、または ImageButton Web コントロールが追加され、レポートに各レコードが表示され、クリックするとポストバックが発生し、サーバー側のコードが呼び出されます。 レコードごとにデータを編集および削除することが最も一般的な例です。 実際、 データの挿入、更新、削除の概要 に関するチュートリアルから見たように、編集と削除は非常に一般的であるため、GridView、DetailsView、および FormView コントロールは、1 行のコードを記述しなくてもこのような機能をサポートできます。

[編集] ボタンと [削除] ボタンに加えて、GridView、DetailsView、および FormView コントロールには、ボタン、LinkButtons、または ImageButtons を含めることもできます。ボタンをクリックすると、カスタム サーバー側ロジックを実行できます。 このチュートリアルでは、テンプレートと GridView コントロールまたは DetailsView コントロールのフィールドの両方にカスタム ボタンを追加する方法について説明します。 特に、ユーザーがサプライヤーをページングできるようにする FormView を持つインターフェイスを構築します。 特定のサプライヤーの場合、FormView には、サプライヤーに関する情報と、ボタン Web コントロールが表示されます。ボタン Web コントロールをクリックすると、関連するすべての製品が廃止済みとしてマークされます。 さらに、GridView には、選択したサプライヤーによって提供された製品が一覧表示され、各行には [価格の引き上げ] ボタンと [割引価格] ボタンが含まれており、クリックした場合は製品を UnitPrice 10% 上げたり下げたりします (図 1 を参照)。

FormView と GridView の両方に、カスタム アクションを実行するボタンが含まれています

図 1: FormView と GridView の両方に、カスタム アクションを実行するボタンが含まれている (フルサイズの画像を表示する場合はクリックします)

手順 1: ボタン チュートリアル Web ページの追加

カスタム ボタンを追加する方法を見る前に、まず、このチュートリアルに必要な ASP.NET ページを Web サイト プロジェクトに作成してみましょう。 まず、 という名前 CustomButtonsの新しいフォルダーを追加します。 次に、次の 2 つの ASP.NET ページをそのフォルダーに追加し、各ページをマスター ページに Site.master 関連付けてください。

  • Default.aspx
  • CustomButtons.aspx

カスタム Buttons-Related チュートリアルの ASP.NET ページを追加する

図 2: カスタム Buttons-Related チュートリアルの ASP.NET ページを追加する

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

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

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

最後に、ページをエントリとしてファイルに Web.sitemap 追加します。 具体的には、ページングと並べ替えの後に次のマークアップを追加します <siteMapNode>

<siteMapNode
    title="Adding Custom Buttons"
    description="Samples of Reports that Include Buttons for Performing
                  Server-Side Actions"
    url="~/CustomButtons/Default.aspx">
    <siteMapNode
        title="Using ButtonFields and Buttons in Templates"
        description="Examines how to add custom Buttons, LinkButtons,
                      or ImageButtons as ButtonFields or within templates."
        url="~/CustomButtons/CustomButtons.aspx" />
</siteMapNode>

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

サイト マップにカスタム ボタンのチュートリアルのエントリが含まれるようになりました

図 4: サイト マップにカスタム ボタンのチュートリアルのエントリが含まれるようになりました

手順 2: 仕入先をListsする FormView を追加する

サプライヤーを一覧表示する FormView を追加して、このチュートリアルを開始しましょう。 「概要」で説明したように、この FormView を使用すると、ユーザーはサプライヤーをページングし、GridView でサプライヤーから提供された製品が表示されます。 さらに、この FormView にはボタンが含まれます。このボタンをクリックすると、サプライヤーのすべての製品が廃止済みとしてマークされます。 カスタム ボタンを FormView に追加する前に、まず、仕入先情報を表示するように FormView を作成します。

まず、 フォルダー内の CustomButtons.aspx ページを CustomButtons 開きます。 FormView をページに追加するには、ツールボックスからDesignerにドラッグし、そのIDプロパティを にSuppliers設定します。 FormView のスマート タグから、 という名前 SuppliersDataSourceの新しい ObjectDataSource を作成することを選択します。

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

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

クラスGetSuppliers()の メソッドからSuppliersBLLクエリを実行するように、この新しい ObjectDataSource を構成します (図 6 を参照)。 この FormView には仕入先情報を更新するためのインターフェイスがないため、[更新] タブのドロップダウン リストから [(なし)] オプションを選択します。

SuppliersBLL クラスの GetSuppliers() メソッドを使用するようにデータ ソースを構成する

図 6: クラスの メソッドを使用するようにデータ ソースをSuppliersBLL構成する (フルサイズのGetSuppliers()画像を表示する 場合はクリックします)

ObjectDataSource を構成すると、Visual Studio によって FormView の 、EditItemTemplate、および ItemTemplate が生成InsertItemTemplateされます。 と EditItemTemplateInsertItemTemplate削除し、ItemTemplate仕入先の会社名と電話番号だけを表示するように を変更します。 最後に、スマート タグの [ページングを有効にする] チェック ボックスをオンにするか、そのプロパティを に設定して、FormView のページングサポートをAllowPagingTrue有効にします。 これらの変更後、ページの宣言型マークアップは次のようになります。

<asp:FormView ID="Suppliers" runat="server" DataKeyNames="SupplierID"
    DataSourceID="SuppliersDataSource" EnableViewState="False" AllowPaging="True">
    <ItemTemplate>
        <h3>
            <asp:Label ID="CompanyName" runat="server"
                Text='<%# Bind("CompanyName") %>' />
        </h3>
        <b>Phone:</b>
        <asp:Label ID="PhoneLabel" runat="server" Text='<%# Bind("Phone") %>' />
    </ItemTemplate>
</asp:FormView>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetSuppliers" TypeName="SuppliersBLL">
</asp:ObjectDataSource>

図 7 は、ブラウザーで表示したときのCustomButtons.aspxページを示しています。

FormView Lists現在選択されている仕入先の CompanyName フィールドと Phone フィールド

図 7: FormView Lists、CompanyName現在選択されている仕入先の フィールドと Phone フィールド (フルサイズの画像を表示する をクリックします)

手順 3: 選択した仕入先の製品をListsする GridView を追加する

FormView のテンプレートに [すべての製品の中止] ボタンを追加する前に、まず、選択したサプライヤーによって提供される製品を一覧表示する FormView の下に GridView を追加しましょう。 これを実現するには、ページに GridView を追加し、その ID プロパティを に SuppliersProducts設定し、 という名前 SuppliersProductsDataSourceの新しい ObjectDataSource を追加します。

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

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

ProductsBLL クラス GetProductsBySupplierID(supplierID) の メソッドを使用するようにこの ObjectDataSource を構成します (図 9 を参照)。 この GridView では製品の価格を調整できますが、組み込みの編集機能や GridView からの機能の削除は使用されません。 したがって、ObjectDataSource の UPDATE、INSERT、DELETE タブのドロップダウン リストを (None) に設定できます。

ProductsBLL クラスの GetProductsBySupplierID(supplierID) メソッドを使用するようにデータ ソースを構成する

図 9: クラスの メソッドを使用するようにデータ ソースをProductsBLL構成する (フルサイズのGetProductsBySupplierID(supplierID)画像を表示する 場合はクリックします)

メソッドは GetProductsBySupplierID(supplierID) 入力パラメーターを受け取るので、ObjectDataSource ウィザードは、このパラメーター値のソースを求めるメッセージを表示します。 FormView から値を SupplierID 渡すには、[パラメーター ソース] ドロップダウン リストを [コントロール] に設定し、[ControlID] ドロップダウン リストを に Suppliers 設定します (手順 2 で作成した FormView の ID)。

supplierID パラメーターが Suppliers FormView コントロールから取得されることを示す

図 10: パラメーターが supplierID FormView コントロールから Suppliers 取得されることを示します (フルサイズの画像を表示するには、ここをクリックします)

ObjectDataSource ウィザードが完了すると、GridView には製品の各データ フィールドの BoundField または CheckBoxField が含まれます。 これをトリミングして、 ProductNameUnitPrice BoundFields だけを CheckBoxField と共 Discontinued に表示しましょう。さらに、BoundField のテキストが通貨として書式設定されるように書式設定しましょう UnitPrice 。 GridView と SuppliersProductsDataSource ObjectDataSource の宣言型マークアップは、次のマークアップのようになります。

<asp:GridView ID="SuppliersProducts" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="SuppliersProductsDataSource"
    EnableViewState="False" runat="server">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            SortExpression="UnitPrice" DataFormatString="{0:C}"
            HtmlEncode="False" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersProductsDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetProductsBySupplierID" TypeName="ProductsBLL">
    <SelectParameters>
        <asp:ControlParameter ControlID="Suppliers" Name="supplierID"
            PropertyName="SelectedValue" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

この時点で、このチュートリアルではマスター/詳細レポートを表示します。これにより、ユーザーは上部の FormView からサプライヤーを選択し、下部の GridView を通じてそのサプライヤーから提供された製品を表示できます。 図 11 は、FormView から東京トレーダーズサプライヤーを選択したときのこのページのスクリーン ショットを示しています。

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

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

手順 4: 仕入先のすべての製品を中止する DAL メソッドと BLL メソッドを作成する

ボタンを FormView に追加する前に、クリックするとすべてのサプライヤーの製品が中止されます。まず、このアクションを実行する DAL と BLL の両方にメソッドを追加する必要があります。 特に、このメソッドには という名前が付けられます DiscontinueAllProductsForSupplier(supplierID)。 FormView のボタンをクリックすると、選択した仕入先 SupplierIDの を渡して、ビジネス ロジック レイヤーでこのメソッドを呼び出します。BLL は対応するデータ アクセス層メソッドを呼び出します。これにより、指定された仕入先の製品を中止するステートメントがデータベースに発行 UPDATE されます。

前のチュートリアルで行ったとおり、ボトムアップ アプローチを使用します。最初に DAL メソッド、BLL メソッドを作成し、最後に ASP.NET ページで機能を実装します。 フォルダー内の Northwind.xsd Typed DataSet を App_Code/DAL 開き、 に新しいメソッドを ProductsTableAdapter 追加します (を右クリックして[クエリの ProductsTableAdapter 追加] を選択します)。 これにより、TableAdapter クエリ構成ウィザードが表示されます。このウィザードでは、新しいメソッドを追加するプロセスについて説明します。 まず、DAL メソッドがアドホック SQL ステートメントを使用することを示します。

アドホック SQL ステートメントを使用して DAL メソッドを作成する

図 12: アドホック SQL ステートメントを使用して DAL メソッドを作成する (フルサイズの画像を表示する] をクリックします)

次に、作成するクエリの種類を確認するメッセージが表示されます。 DiscontinueAllProductsForSupplier(supplierID)メソッドはデータベース テーブルを更新Productsする必要があるため、指定した supplierIDによって提供されるすべての製品の フィールドを 1 に設定Discontinuedし、データを更新するクエリを作成する必要があります。

UPDATE クエリの種類を選択する

図 13: UPDATE クエリの種類を選択する (フルサイズの画像を表示する場合にクリックします)

次のウィザード画面には、DataTable で定義されている各フィールドを更新する TableAdapter の既存 UPDATE のステートメントが Products 表示されます。 このクエリ テキストを次のステートメントに置き換えます。

UPDATE [Products] SET
   Discontinued = 1
WHERE SupplierID = @SupplierID

このクエリを入力して [次へ] をクリックすると、最後のウィザード画面で新しいメソッドの名前の使用 DiscontinueAllProductsForSupplierが求められます。 [完了] ボタンをクリックしてウィザードを完了します。 DataSet Designerに戻ると、 という名前DiscontinueAllProductsForSupplier(@SupplierID)の に新しいメソッドがProductsTableAdapter表示されます。

New DAL メソッドに「中止AllProductsForSupplier」という名前を付けます

図 14: 新しい DAL メソッド DiscontinueAllProductsForSupplier に名前を付ける (フルサイズの画像を表示する をクリックします)

DiscontinueAllProductsForSupplier(supplierID)データ アクセス層でメソッドを作成する次のタスクは、ビジネス ロジックレイヤーで メソッドを作成DiscontinueAllProductsForSupplier(supplierID)することです。 これを行うには、クラス ファイルを ProductsBLL 開き、次を追加します。

public int DiscontinueAllProductsForSupplier(int supplierID)
{
    return Adapter.DiscontinueAllProductsForSupplier(supplierID);
}

このメソッドは、指定されたsupplierIDパラメーター値をDiscontinueAllProductsForSupplier(supplierID)渡して、DAL 内の メソッドを呼び出すだけです。 特定の状況でサプライヤーの製品の中止のみを許可するビジネス ルールがある場合は、BLL でこれらのルールをここで実装する必要があります。

注意

クラスのUpdateProductオーバーロードProductsBLLとは異なり、メソッド シグネチャDiscontinueAllProductsForSupplier(supplierID)には 属性 (<System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, Boolean)>) はDataObjectMethodAttribute含まれません。 これにより、ObjectDataSource の DiscontinueAllProductsForSupplier(supplierID) [データ ソースの構成] ウィザードの [更新] タブのドロップダウン リストからメソッドが除外されます。この属性は省略しました。これは、ASP.NET ページのイベント ハンドラーからメソッドを直接呼び出 DiscontinueAllProductsForSupplier(supplierID) すことになるためです。

手順 5: FormView に [すべての製品を中止する] ボタンを追加する

BLL と DAL のメソッドが DiscontinueAllProductsForSupplier(supplierID) 完了したら、選択した仕入先のすべての製品を中止する機能を追加する最後の ItemTemplate手順は、FormView の に Button Web コントロールを追加することです。 仕入先の電話番号の下に、ボタン テキストの [すべての製品を中止する] とプロパティ値 DiscontinueAllProductsForSupplierを指定して、このようなボタンをID追加しましょう。 この Button Web コントロールを追加するには、FormView のスマート タグの [テンプレートの編集] リンク (図 15 を参照) をクリックするか、宣言構文を使用して直接、Designerを使用します。

FormView の ItemTemplate に [すべての製品の中止] ボタン Web コントロールを追加する

図 15: FormView に [すべての製品の中止] ボタン Web コントロールを追加する (フルサイズのItemTemplate画像を表示する をクリックします)

ページにアクセスするユーザーがボタンをクリックすると、ポストバックが発生し、FormView の ItemCommand イベント が発生します。 このボタンがクリックされた場合に応答してカスタム コードを実行するには、このイベントのイベント ハンドラーを作成します。 ただし、FormView 内で ItemCommandButton、 LinkButton、または ImageButton Web コントロールがクリックされるたびにイベントが発生することを理解します。 つまり、ユーザーが FormView 内のあるページから別のページに移動すると、 ItemCommand イベントが発生します。挿入、更新、または削除をサポートする FormView でユーザーが [新規]、[編集]、または [削除] をクリックしたときと同じことが発生します。

クリックされた ItemCommand ボタンに関係なく が発生するため、イベント ハンドラーでは、[すべての製品を中止] ボタンがクリックされたかどうか、または他のボタンであるかどうかを判断する方法が必要です。 これを実現するために、Button Web コントロールの プロパティを特定の CommandName 値に設定できます。 ボタンがクリックされると、この CommandName 値がイベント ハンドラーに ItemCommand 渡され、[すべての製品を中止] ボタンがクリックされたボタンであるかどうかを判断できます。 [すべての製品を中止] ボタンの CommandName プロパティを [Products] に設定します。

最後に、クライアント側の確認ダイアログ ボックスを使用して、選択した仕入先の製品をユーザーが本当に中止することを確認します。 「 削除時の Client-Side 確認の追加 」チュートリアルで説明したように、これは少しの JavaScript で実現できます。 特に、Button Web コントロールの OnClientClick プロパティを に設定します。 return confirm('This will mark _all_ of this supplier\'s products as discontinued. Are you certain you want to do this?');

これらの変更を行った後、FormView の宣言型構文は次のようになります。

<asp:FormView ID="Suppliers" runat="server" DataKeyNames="SupplierID"
    DataSourceID="SuppliersDataSource" EnableViewState="False"
    AllowPaging="True">
    <ItemTemplate>
        <h3><asp:Label ID="CompanyName" runat="server"
            Text='<%# Bind("CompanyName") %>'></asp:Label></h3>
        <b>Phone:</b>
        <asp:Label ID="PhoneLabel" runat="server" Text='<%# Bind("Phone") %>' />
        <br />
        <asp:Button ID="DiscontinueAllProductsForSupplier" runat="server"
            CommandName="DiscontinueProducts" Text="Discontinue All Products"
            OnClientClick="return confirm('This will mark _all_ of this supplier\'s
                products as discontinued. Are you certain you want to do this?');" />
    </ItemTemplate>
</asp:FormView>

次に、FormView ItemCommand のイベントのイベント ハンドラーを作成します。 このイベント ハンドラーでは、まず [すべての製品を中止] ボタンがクリックされたかどうかを判断する必要があります。 その場合は、 クラスのインスタンスを作成し、そのDiscontinueAllProductsForSupplier(supplierID)メソッドをProductsBLL呼び出し、選択した FormView の をSupplierID渡します。

protected void Suppliers_ItemCommand(object sender, FormViewCommandEventArgs e)
{
    if (e.CommandName.CompareTo("DiscontinueProducts") == 0)
    {
        // The "Discontinue All Products" Button was clicked.
        // Invoke the ProductsBLL.DiscontinueAllProductsForSupplier(supplierID) method
        // First, get the SupplierID selected in the FormView
        int supplierID = (int)Suppliers.SelectedValue;
        // Next, create an instance of the ProductsBLL class
        ProductsBLL productInfo = new ProductsBLL();
        // Finally, invoke the DiscontinueAllProductsForSupplier(supplierID) method
        productInfo.DiscontinueAllProductsForSupplier(supplierID);
    }
}

SupplierID FormView で現在選択されている仕入先の には、FormView の SelectedValue プロパティを使用してアクセスできることに注意してください。 プロパティは SelectedValue 、FormView に表示されるレコードの最初のデータ キー値を返します。 FormView の プロパティは、データ キー値のDataKeyNames取得元となるデータ フィールドを示します。これは、手順 2 で ObjectDataSource を FormView にSupplierIDバインドするときに、Visual Studio によって自動的に に設定されました。

イベント ハンドラーが ItemCommand 作成されたら、少し時間を取ってページをテストします。 協力的なデケソス'ラスカブラス'サプライヤーを参照してください(それは私のためのFormViewの5番目のサプライヤーです)。 このサプライヤーは、Queso Cabrales と Queso Manchego La Pastora の 2 つの製品を提供しています。どちらも廃止 されていません

協力者デ ケソス 'ラス カブラス' が廃業したため、その製品が廃止される予定であることを想像してください。 [すべての製品を中止する] ボタンをクリックします。 これにより、クライアント側の確認ダイアログ ボックスが表示されます (図 16 を参照)。

協力的なデQuesosラスカブラスは、2つのアクティブな製品を供給します

図 16: 共同で Quesos ラス カブラス供給 2 つのアクティブな製品 (フルサイズの画像を表示する をクリックします)

クライアント側の確認ダイアログ ボックスで [OK] をクリックすると、フォームの送信が続行され、FormView ItemCommand のイベントが発生するポストバックが発生します。 作成したイベント ハンドラーが実行され、 メソッドが DiscontinueAllProductsForSupplier(supplierID) 呼び出され、Queso Cabrales と Queso Manchego La Pastora 製品の両方が廃止されます。

GridView のビュー ステートを無効にした場合、GridView はポストバックごとに基になるデータ ストアにリバウンドされるため、これら 2 つの製品が廃止されたことを反映するように直ちに更新されます (図 17 を参照)。 ただし、GridView でビューステートを無効にしていない場合は、この変更を行った後にデータを GridView に手動で再バインドする必要があります。 これを実現するには、 メソッドを呼び出した直後に GridView の DataBind() メソッドを DiscontinueAllProductsForSupplier(supplierID) 呼び出します。

[すべての製品を中止する] ボタンをクリックすると、サプライヤーの製品が適宜更新されます

図 17: [すべての製品の中止] ボタンをクリックすると、仕入先の製品が適宜更新されます (クリックするとフルサイズの画像が表示されます)

手順 6: 製品の価格を調整するためのビジネス ロジック レイヤーで UpdateProduct オーバーロードを作成する

FormView の [すべての製品を中止する] ボタンと同様に、GridView で製品の価格を増減するためのボタンを追加するには、まず適切なデータ アクセス層とビジネス ロジック層のメソッドを追加する必要があります。 DAL の 1 つの製品行を更新するメソッドが既に用意されているため、BLL で メソッドの新しいオーバーロード UpdateProduct を作成することで、このような機能を提供できます。

過去 UpdateProduct のオーバーロードでは、製品フィールドの組み合わせをスカラー入力値として取り込み、指定された製品のフィールドだけを更新しました。 このオーバーロードでは、この標準とは若干異なり、代わりに製品 ProductID の と を調整 UnitPrice する割合を渡します (新しい調整済 UnitPrice み自体を渡すのではなく)。 この方法では、現在の製品 UnitPriceの を決定する必要がないため、ASP.NET ページ分離コード クラスで記述する必要があるコードが簡略化されます。

UpdateProductこのチュートリアルのオーバーロードを次に示します。

public bool UpdateProduct(decimal unitPriceAdjustmentPercentage, int productID)
{
    Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
    if (products.Count == 0)
        // no matching record found, return false
        return false;
    Northwind.ProductsRow product = products[0];
    // Adjust the UnitPrice by the specified percentage (if it's not NULL)
    if (!product.IsUnitPriceNull())
        product.UnitPrice *= unitPriceAdjustmentPercentage;
    // Update the product record
    int rowsAffected = Adapter.Update(product);
    // Return true if precisely one row was updated, otherwise false
    return rowsAffected == 1;
}

このオーバーロードは、DAL GetProductByProductID(productID) の メソッドを使用して、指定した製品に関する情報を取得します。 次に、製品 UnitPrice にデータベース NULL 値が割り当てられているかどうかを確認します。 その場合、価格は変更されません。 ただし、値NULLUnitPrice以外の値がある場合、メソッドは指定した割合 (unitPriceAdjustmentPercent) で製品UnitPriceを更新します。

手順 7: GridView に増減ボタンを追加する

GridView (と DetailsView) はどちらもフィールドのコレクションで構成されます。 BoundFields、CheckBoxFields、TemplateFields に加えて、ASP.NET には ButtonField が含まれており、その名前が示すように、各行の Button、LinkButton、または ImageButton を持つ列としてレンダリングされます。 FormView と同様に、GridView ページング ボタン、編集または削除ボタン、並べ替えボタンなどのボタンをクリックすると、ポストバックが発生し、GridView RowCommandイベントが発生します。

ButtonField には、 CommandName 指定した値を各 Buttons プロパティに割り当てるプロパティがあります CommandName 。 FormView と同様に、 CommandName 値はイベント ハンドラーによって使用され RowCommand 、どのボタンがクリックされたかを判断します。

2 つの新しい ButtonFields を GridView に追加してみましょう。1 つはボタン テキスト Price +10% で、もう 1 つは Price -10% というテキストを含みます。 これらの ButtonField を追加するには、GridView のスマート タグから [列の編集] リンクをクリックし、左上のリストから ButtonField フィールドの種類を選択し、[追加] ボタンをクリックします。

GridView に 2 つの ButtonField を追加する

図 18: GridView に 2 つの ButtonField を追加する

2 つの ButtonField を移動して、最初の 2 つの GridView フィールドとして表示されるようにします。 次に Text 、これら 2 つの ButtonFields のプロパティを Price +10% と Price -10% に設定し CommandName 、プロパティをそれぞれ IncreasePrice と DecreasePrice に設定します。 既定では、ButtonField はボタンの列を LinkButtons としてレンダリングします。 ただし、これは ButtonField ButtonType の プロパティを使用して変更できます。 これら 2 つの ButtonFields を通常のプッシュ ボタンとしてレンダリングしてみましょう。そのため、 プロパティを に設定しますButtonTypeButton。 図 19 は、これらの変更が行われた後の [フィールド] ダイアログ ボックスを示しています。GridView の宣言型マークアップを次に示します。

ButtonFields Text、CommandName、ButtonType の各プロパティを構成する

図 19: ButtonFields、、CommandName、および ButtonType プロパティをText構成する

<asp:GridView ID="SuppliersProducts" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="SuppliersProductsDataSource"
    EnableViewState="False">
    <Columns>
        <asp:ButtonField ButtonType="Button" CommandName="IncreasePrice"
            Text="Price +10%" />
        <asp:ButtonField ButtonType="Button" CommandName="DecreasePrice"
            Text="Price -10%" />
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            SortExpression="UnitPrice" DataFormatString="{0:C}"
            HtmlEncode="False" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Columns>
</asp:GridView>

これらの ButtonFields を作成したら、最後の手順として GridView RowCommand のイベントのイベント ハンドラーを作成します。 このイベント ハンドラーは、Price +10% または Price -10% ボタンがクリックされたために発生した場合、ボタンがクリックされた行の をProductID決定し、クラスの UpdateProduct メソッドを呼び出ProductsBLLし、 と共ProductIDに適切なUnitPrice割合の調整を渡す必要があります。 次のコードは、これらのタスクを実行します。

protected void SuppliersProducts_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName.CompareTo("IncreasePrice") == 0 ||
        e.CommandName.CompareTo("DecreasePrice") == 0)
    {
        // The Increase Price or Decrease Price Button has been clicked
        // Determine the ID of the product whose price was adjusted
        int productID =
            (int)SuppliersProducts.DataKeys[Convert.ToInt32(e.CommandArgument)].Value;
        // Determine how much to adjust the price
        decimal percentageAdjust;
        if (e.CommandName.CompareTo("IncreasePrice") == 0)
            percentageAdjust = 1.1M;
        else
            percentageAdjust = 0.9M;

        // Adjust the price
        ProductsBLL productInfo = new ProductsBLL();
        productInfo.UpdateProduct(percentageAdjust, productID);
    }
}

[価格 + 10%] または [価格 -10%] ボタンがクリックされた行の を確認 ProductID するには、GridView の DataKeys コレクションを参照する必要があります。 このコレクションは、各 GridView 行の プロパティで DataKeyNames 指定されたフィールドの値を保持します。 ObjectDataSource を GridView にバインドするときに、Visual Studio によって GridView DataKeyNames の プロパティが ProductID に設定されているため、DataKeys(rowIndex).Value指定した rowIndex に 対して がProductID提供されます。

ButtonField は、 パラメーターを通じてe.CommandArgumentボタンがクリックされた行の rowIndex を自動的に渡します。 したがって、Price +10% または Price -10% ボタンがクリックされた行の を決定 ProductID するには、 を使用します Convert.ToInt32(SuppliersProducts.DataKeys(Convert.ToInt32(e.CommandArgument)).Value)

[すべての製品を中止] ボタンと同様に、GridView のビューステートを無効にした場合、GridView はポストバックごとに基になるデータ ストアにリバウンドされるため、いずれかのボタンをクリックした場合に発生する価格の変更を反映するように直ちに更新されます。 ただし、GridView でビューステートを無効にしていない場合は、この変更を行った後にデータを GridView に手動で再バインドする必要があります。 これを実現するには、 メソッドを呼び出した直後に GridView の DataBind() メソッドを UpdateProduct 呼び出します。

図 20 は、おばあちゃんケリーのホームステッドが提供する製品を表示するときのページを示しています。 図 21 は、[価格 + 10%] ボタンが [おばあちゃんのボイセンベリー スプレッド] で 2 回クリックされた後の結果と、Northwoods Cranberry Sauce の場合は [Price -10%] ボタンが 1 回クリックされた後の結果を示しています。

GridView には、価格 +10% ボタンと価格 -10% ボタンが含まれています

図 20: GridView には、価格 +10% ボタンと価格 -10% ボタンが含まれています (フルサイズの画像を表示する をクリックします)

1 番目と 3 番目の製品の価格は、価格 +10% ボタンと価格 -10% ボタンを使用して更新されました

図 21: 価格 +10% ボタンと価格 -10% ボタンを使用して 1 番目と 3 番目の製品の価格が更新されました (フルサイズの画像を表示する をクリックします)。

注意

GridView (および DetailsView) では、Buttons、LinkButtons、または ImageButtons を TemplateFields に追加することもできます。 BoundField と同様に、これらのボタンをクリックするとポストバックが発生し、GridView の RowCommand イベントが発生します。 ただし、TemplateField にボタンを追加する場合、ButtonFields を使用する場合と同様に、Button CommandArgument の は行のインデックスに自動的に設定されません。 イベント ハンドラー内 RowCommand でクリックされたボタンの行インデックスを確認する必要がある場合は、次のようなコードを使用して、TemplateField 内の宣言構文で Button CommandArgument の プロパティを手動で設定する必要があります。
<asp:Button runat="server" ... CommandArgument='<%# ((GridViewRow) Container).RowIndex %>'.

まとめ

GridView、DetailsView、および FormView の各コントロールには、Buttons、LinkButtons、または ImageButtons を含めることができます。 このようなボタンをクリックすると、ポストバックが発生し、FormView コントロールと DetailsView コントロールと RowCommand GridView のイベントでイベントが発生ItemCommandします。 これらのデータ Web コントロールには、レコードの削除や編集など、コマンド関連の一般的なアクションを処理する機能が組み込まれています。 ただし、ボタンを使用して、クリックすると独自のカスタム コードを実行して応答することもできます。

これを実現するには、 または RowCommand イベントのイベント ハンドラーを作成するItemCommand必要があります。 このイベント ハンドラーでは、最初に受信CommandName値をチェックして、クリックされたボタンを特定してから、適切なカスタム アクションを実行します。 このチュートリアルでは、ボタンと ButtonFields を使用して、指定したサプライヤーのすべての製品を中止するか、特定の製品の価格を 10% 増減させる方法について説明しました。

プログラミングに満足!

著者について

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