編集および挿入インターフェイスに検証コントロールを追加する (C#)

作成者: Scott Mitchell

PDF のダウンロード

このチュートリアルでは、データ Web コントロールの EditItemTemplate と InsertItemTemplate に検証コントロールを追加して、より間違えにくいユーザー インターフェイスにする方法について説明します。

はじめに

前の 3 つのチュートリアルで説明した例での GridView および DetailsView コントロールはすべて、BoundField と CheckBoxField から成ります (これらのフィールド種類は、スマート タグを介して GridView または DetailsView をデータ ソース コントロールにバインドするときに Visual Studio によって自動的に追加されます)。 GridView 内や DetailsView 内の行を編集する場合は、読み取り専用でない BoundField がテキスト ボックスに変換され、そこでエンド ユーザーが既存のデータを変更できます。 同様に、DetailsView コントロールに新しいレコードを挿入する場合は、InsertVisible プロパティが true (既定値) に設定されている BoundField が、空のテキスト ボックスとしてレンダリングされ、そこでユーザーが新しいレコードのフィールド値を指定できます。 同じく、CheckBoxField (これは、標準の読み取り専用インターフェイスでは無効になっている) は、編集および挿入インターフェイスでは、有効なチェック ボックスに変換されます。

BoundField と CheckBoxField の既定の編集および挿入インターフェイスは役立ちますが、そのインターフェイスには何も検証がありません。 ProductName フィールドへの入力を忘れる、UnitsInStock に無効な値 (-50 など) を入力するなど、ユーザーがデータ入力を間違えた場合は、アプリケーション アーキテクチャの深部から例外が発生します。 この例外は、前のチュートリアルで示したように適切に処理できますが、編集または挿入ユーザー インターフェイスに、そもそもこのような無効なデータを入力できないようにするための検証コントロールがあると理想的です。

カスタマイズされた編集または挿入インターフェイスにするには、BoundField または CheckBoxField を TemplateField に置き換える必要があります。 TemplateField (これは、「GridView コントロールで TemplateFields を使用する」と「DetailsView コントロールで TemplateFields を使用する」で説明したトピックです) は、行のさまざまな状態に対して別々のインターフェイスを定義する複数のテンプレートから成ります。 TemplateField の ItemTemplate は、DetailsView または GridView コントロールで読み取り専用フィールドまたは行をレンダリングするときに使います。一方、EditItemTemplateInsertItemTemplate はそれぞれ、編集および挿入モードで使うインターフェイスを示します。

このチュートリアルでは、TemplateField の EditItemTemplateInsertItemTemplate に検証コントロールを追加して、より間違えにくいユーザー インターフェイスにする方法について説明します。 具体的には、このチュートリアルでは、「挿入、更新、削除に関連付けられているイベントを調べる」チュートリアルで作成した例を利用し、適切な検証を含むように編集および挿入インターフェイスを拡張します。

手順 1: 「挿入、更新、削除に関連付けられているイベントを調べる」にある例を複製する

挿入、更新、削除に関連付けられているイベントを調べる」チュートリアルでは、編集可能な GridView で製品の名前と価格を一覧表示するページを作成しました。 また、そのページには DetailsView が含まれており、これは DefaultMode プロパティが Insert に設定されているため必ず挿入モードでレンダリングされます。 この DetailsView から、ユーザーが新しい製品の名前と価格を入力し、[挿入] をクリックしてそれをシステムに追加できます (図 1 を参照)。

前の例では、ユーザーは新しい製品を追加し、既存の製品を編集できます

図 1: 前の例でユーザーが新しい製品の追加と既存製品の編集ができるようになった (フルサイズの画像を表示するにはこちらをクリックします)

このチュートリアルの目的は、DetailsView と GridView を拡張して検証コントロールを提供することです。 具体的には、検証ロジックで以下を行います。

  • 製品の挿入時や編集時に名前を指定する必要がある
  • レコードの挿入時に価格を指定する必要がある。レコードの編集時は、引き続き価格が必要となりますが、前のチュートリアルから既に存在していた、GridView の RowUpdating イベント ハンドラーでのプログラム ロジックを使います
  • 価格に入力された値が有効な通貨形式であることを確認する

前の例を拡張して検証を含める前に、まず、DataModificationEvents.aspx ページからの例をこのチュートリアル用のページ UIValidation.aspx に複製する必要があります。 これを実現するには、DataModificationEvents.aspx ページの宣言マークアップとそのソース コードを両方コピーする必要があります。 まず、次の手順を実行して、宣言マークアップをコピーします。

  1. Visual Studio で DataModificationEvents.aspx ページを開きます。
  2. そのページの宣言マークアップに移動します (ページの下部にある [ソース] ボタンをクリックします)
  3. 図 2 に示すように、<asp:Content> および </asp:Content> タグ内のテキスト (3 行目から 44 行目) をコピーします。

<asp:Content> コントロール内のテキストをコピーする

図 2: <asp:Content> コントロール内のテキストをコピーする (フルサイズの画像を表示するにはをクリックします)

  1. UIValidation.aspx ページを開きます
  2. そのページの宣言マークアップに移動します
  3. <asp:Content> コントロール内にテキストを貼り付けます

ソース コードをコピーするには、DataModificationEvents.aspx.cs ページを開き、EditInsertDelete_DataModificationEvents クラス "内" のテキストのみをコピーします。 3 つのイベント ハンドラー (Page_LoadGridView1_RowUpdatingObjectDataSource1_Inserting) をコピーしますが、クラスの宣言や using ステートメントはコピーしません。 コピーしたテキストを UIValidation.aspx.csEditInsertDelete_UIValidation クラス "内" に 貼り付けます。

コンテンツとコードを DataModificationEvents.aspx から UIValidation.aspx に移動した後、ブラウザーで進展内容をテストします。 これら 2 つの各ページに同じ出力が表示され、同じ機能があることがわかります (実際の DataModificationEvents.aspx のスクリーン ショットについては、図 1 を参照)。

手順 2: BoundField を TemplateField に変換する

編集および挿入インターフェイスに検証コントロールを追加するには、DetailsView および GridView コントロールで使われている BoundField を、TemplateField に変換する必要があります。 これを実現するには、GridView と DetailsView のスマート タグでそれぞれ [列の編集] リンクと [フィールドの編集] リンクをクリックします。 次に、BoundField をそれぞれ選択し、[このフィールドを TemplateField に変換します。] リンクをクリックします。

DetailsView と GridView の各 BoundFields を TemplateFields に変換する

図 3: DetailsView と GridView の BoundField をそれぞれ TemplateField に変換する (フルサイズの画像を表示するにはこちらをクリックします)

[フィールド] ダイアログ ボックスを使って BoundField を TemplateField に変換すると、BoundField 自体と同一の、読み取り専用の編集および挿入インターフェイスを表示する TemplateField が生成されます。 次のマークアップは、TemplateField に変換された後の DetailsView での ProductName フィールドの宣言構文を示しています:

<asp:TemplateField HeaderText="ProductName" SortExpression="ProductName">
    <EditItemTemplate>
        <asp:TextBox ID="TextBox1" runat="server"
         Text='<%# Bind("ProductName") %>'></asp:TextBox>
    </EditItemTemplate>
    <InsertItemTemplate>
        <asp:TextBox ID="TextBox1" runat="server"
         Text='<%# Bind("ProductName") %>'></asp:TextBox>
    </InsertItemTemplate>
    <ItemTemplate>
        <asp:Label ID="Label1" runat="server"
         Text='<%# Bind("ProductName") %>'></asp:Label>
    </ItemTemplate>
</asp:TemplateField>

この TemplateField には ItemTemplateEditItemTemplateInsertItemTemplate という 3 つのテンプレートが自動的に作成されていることに注目してください。 ItemTemplate では、Label Web コントロールを使って単一のデータ フィールド値 (ProductName) が表示されますが、EditItemTemplateInsertItemTemplate では、そのデータ フィールド値が TextBox Web コントロールに表示されます。この場合は、双方向データ バインドを使ってその TextBox の Text プロパティにそのデータ フィールドが関連付けられています。 このページでは DetailsView を挿入用にのみ使っているため、2 つの TemplateField からItemTemplateEditItemTemplate を削除することもできますが、残してもかまいません。

GridView では DetailsView の組み込みの挿入機能がサポートされていないため、GridView の ProductName フィールドを TemplateField に変換すると、ItemTemplateEditItemTemplate のみになります:

<asp:TemplateField HeaderText="ProductName" SortExpression="ProductName">
    <EditItemTemplate>
        <asp:TextBox ID="TextBox1" runat="server"
         Text='<%# Bind("ProductName") %>'></asp:TextBox>
    </EditItemTemplate>
    <ItemTemplate>
        <asp:Label ID="Label1" runat="server"
          Text='<%# Bind("ProductName") %>'></asp:Label>
    </ItemTemplate>
</asp:TemplateField>

[このフィールドを TemplateField に変換します。] をクリックすると、Visual Studio で、変換された BoundField のユーザー インターフェイスを模倣したテンプレートがある、TemplateField が作成されます。 これを確認するには、ブラウザーからこのページにアクセスします。 TemplateField の外観と動作が、代わりに BoundField が使われているときのエクスペリエンスと同じであることがわかります。

Note

必要に応じてそれらのテンプレートでの編集インターフェイスをカスタマイズしてかまいません。 たとえば、UnitPrice TemplateField での TextBox を、ProductName より小さいテキスト ボックスとしてレンダリングする必要があるとします。 これを実現するには、その TextBox の Columns プロパティを適切な値に設定するか、Width プロパティを使って絶対幅を指定します。 次のチュートリアルでは、TextBox を代わりのデータ入力 Web コントロールに置き換えて編集インターフェイスを完全にカスタマイズする方法について説明します。

手順 3: GridView の EditItemTemplate に検証コントロールを追加する

データ入力フォームを作成するときは、ユーザーがすべての必須フィールドに入力し、提供された入力すべてが、適切に書式設定された有効な値であることが重要です。 ユーザーの入力が有効であることの確認に役立つように、ASP.NET では、単一入力コントロールの値を検証するために使える設計になっている、次の 5 つの組み込み検証コントロールが提供されています:

  • RequiredFieldValidator は、値が指定されていることを確認します
  • CompareValidator は、別の Web コントロール値または定数値に対して値を検証するか、値の形式が指定したデータ型に対して有効であることを確認します
  • RangeValidator は、値が値の範囲内にあることを確認します
  • RegularExpressionValidator は、正規表現に対して値を検証します
  • CustomValidator は、カスタムのユーザー定義メソッドに対して値を検証します

これら 5 つのコントロールについて詳しくは、ASP.NET クイック スタート チュートリアル検証コントロールに関する項をご確認ください。

このチュートリアルでは、DetailsView と GridView の ProductName TemplateField 両方で RequiredFieldValidator を使い、DetailsView の UnitPrice TemplateField で RequiredFieldValidator を使う必要があります。 さらに、両方のコントロールの UnitPrice TemplateField に CompareValidator を追加する必要があります。これにより、入力された価格の値が 0 以上であり、有効な通貨形式で表されていることが確認されます。

Note

ASP.NET 1.x にはこれらと同じ 5 つの検証コントロールがありましたが、ASP.NET 2.0 では、多数の改良が加えられています。主要な 2 つとして、Internet Explorer 以外のブラウザーでのクライアント側スクリプトのサポートと、ページ上の検証コントロールを検証グループに分ける機能があります。

まず、GridView の TemplateField での EditItemTemplate に、必要な検証コントロールを追加しましょう。 これを行うには、GridView のスマート タグから [テンプレートの編集] リンクをクリックしてテンプレート編集インターフェイスを表示します。 ここで、編集するテンプレートをドロップダウン リストから選択できます。 編集インターフェイスを拡張するため、検証コントロールを ProductNameUnitPriceEditItemTemplate に追加する必要があります。

ProductName と UnitPrice の EditItemTemplates を拡張する必要がある

図 4: ProductNameUnitPriceEditItemTemplate を拡張する必要がある (フルサイズの画像を表示するにはこちらをクリックします)

ProductName EditItemTemplateで、ツールボックスからテンプレート編集インターフェイスにドラッグして、TextBox の後に配置して RequiredFieldValidator を追加します。

ProductName EditItemTemplate に RequiredFieldValidator を追加する

図 5: requiredFieldValidator を ProductName EditItemTemplate に追加する (フルサイズの画像を表示するには)

すべての検証コントロールは、単一の ASP.NET Web コントロールの入力を検証することによって機能します。 そのため、先ほど追加した RequiredFieldValidator での検証対象が EditItemTemplate 内の TextBox であることを指定する必要があります。これを実現するには、検証コントロールの ControlToValidate プロパティを適切な Web コントロールの ID に設定します。 現在、その TextBox の IDTextBox1 という特徴のない名前ですが、より適切な名前に変更しましょう。 テンプレートでそのテキスト ボックスをクリックし、プロパティ ウィンドウで、IDTextBox1 から EditProductName に変更します。

TextBox の ID を EditProductName に変更する

図 6: TextBox の IDEditProductName に変更する (フルサイズの画像を表示するにはこちらをクリックします)

次に、RequiredFieldValidator の ControlToValidate プロパティを EditProductName に設定します。 最後に、ErrorMessage プロパティを "You must provide the product's name" に、Text プロパティを "*" に設定します。 Text プロパティ値 (指定されている場合) は、検証が失敗した場合に検証コントロールによって表示されるテキストです。 必須の ErrorMessage プロパティ値は ValidationSummary コントロールによって使われます。また、Text プロパティ値を省略した場合は、ErrorMessage プロパティ値が、無効な入力に対して検証コントロールによって表示されるテキストとなります。

RequiredFieldValidator のこれら 3 つのプロパティを設定すると、画面は図 7 のようになります。

RequiredFieldValidator の ControlToValidate、ErrorMessage、および Text プロパティを設定する

図 7: RequiredFieldValidator の ControlToValidateErrorMessageText プロパティを設定する (フルサイズの画像を表示するにはクリックします)

RequiredFieldValidator が ProductName EditItemTemplateに追加されたので、残っているのは、必要な検証を UnitPrice EditItemTemplateに追加することです。 以前に決めたとおり、このページの場合は、レコードの編集時に UnitPrice を省略してかまわないため、RequiredFieldValidator を追加する必要はありません。 ただし、CompareValidator を追加して、UnitPrice が指定された場合は、通貨として適切に書式設定され、0 以上であることを確認する必要があります。

UnitPrice EditItemTemplateに CompareValidator を追加する前に、まず TextBox Web コントロールの ID を TextBox2 から EditUnitPrice に変更しましょう。 この変更を加えた後、CompareValidator を追加し、その ControlToValidate プロパティを EditUnitPrice に、その ErrorMessage プロパティを "The price must be greater than or equal to zero and cannot include the currency symbol" に、その Text プロパティを "*" に設定します。

UnitPrice の値は 0 以上である必要があることを指定するには、CompareValidator の Operator プロパティGreaterThanEqual に、その ValueToCompare プロパティを "0" に、その Type プロパティCurrency に設定します。 次の宣言構文は、これらの変更が加えられた後の UnitPrice TemplateField のEditItemTemplate を示しています:

<EditItemTemplate>
    <asp:TextBox ID="EditUnitPrice" runat="server"
      Text='<%# Bind("UnitPrice", "{0:c}") %>'
      Columns="6"></asp:TextBox>
    <asp:CompareValidator ID="CompareValidator1" runat="server"
        ControlToValidate="EditUnitPrice"
        ErrorMessage="The price must be greater than or equal to zero and
                       cannot include the currency symbol"
        Operator="GreaterThanEqual" Type="Currency"
        ValueToCompare="0">*</asp:CompareValidator>
</EditItemTemplate>

これらの変更を行った後、ブラウザーでページを開きます。 商品の編集時に名前を省略したり、無効な価格値を入力しようとすると、テキスト ボックスの横にアスタリスクが表示されます。 図 8 に示すように、$19.95 のように通貨記号を含む価格値は、無効と見なされます。 CompareValidator の Currency Type では、桁区切り記号 (カルチャの設定に応じてコンマやピリオドなど) と先頭のプラス記号またはマイナス記号を使用できますが、通貨記号 許可されません 。 この動作は、編集インターフェイスが現在通貨形式を使用して UnitPrice をレンダリングするため、ユーザーを困惑させる可能性があります。

Note

挿入、更新、および削除に関連付けられているイベントに関するチュートリアルで、通貨として書式設定するために BoundField の DataFormatString プロパティを {0:c} に設定したことを思い出してください。 さらに、ApplyFormatInEditMode プロパティを true に設定して、GridView の編集インターフェイスで UnitPrice が通貨として書式設定されるようにしました。 BoundField を TemplateField に変換するときに、Visual Studio でこれらの設定が認識され、データバインド構文 <%# Bind("UnitPrice", "{0:c}") %>.を使って TextBox の Text プロパティが通貨として書式設定されました。

入力が無効なテキスト ボックスの横にアスタリスクが表示される

図 8: 入力が無効なテキスト ボックスの横にアスタリスクが表示される (フルサイズの画像を表示するにはこちらをクリックします)

検証は想定通りに動作しますが、ユーザーはレコードを編集するときに通貨記号を手動で削除する必要があり、これは許容できません。 これを解決するには、次の 3 つの選択肢があります:

  1. UnitPrice の値が通貨として書式設定されないように EditItemTemplate を構成します。
  2. CompareValidator を削除し、正しく書式設定された通貨値かどうかを適切に確認する RegularExpressionValidator にそれを置き換えて、ユーザーが通貨記号を入力できるようにします。 ここでの問題は、通貨値を検証する正規表現が簡単ではなく、カルチャ設定を組み込む場合にはコードを記述する必要があるということです。
  3. 検証コントロールをすべて削除し、GridView の RowUpdating イベント ハンドラーでのサーバー側検証ロジックを利用します。

この演習では、選択肢 1 を使いましょう。 現在、UnitPrice は、EditItemTemplate でのその TextBox 用のデータバインド式 (<%# Bind("UnitPrice", "{0:c}") %>) により、通貨値として書式設定されています。 Bind ステートメントを Bind("UnitPrice", "{0:n2}") に変更します。それにより、結果が、有効桁数 2 桁の数値として書式設定されます。 これは、宣言構文を使って直接行うことも、UnitPrice TemplateField の EditItemTemplate での EditUnitPrice TextBox から [DataBindings の編集] リンクをクリックして行うこともできます (図 9 と 10 を参照)。

TextBox の [DataBindings の編集] リンクをクリックします

図 9: TextBox の [DataBindings の編集] リンクをクリックする (フルサイズの画像を表示するにはこちらをクリックします)

Bind ステートメントで書式指定子を指定する

図 10: Bind ステートメントで書式指定子を指定する (フルサイズの画像を表示するにはこちらをクリックします)

この変更により、編集インターフェイスの書式設定された価格には、グループ区切り記号としてコンマと小数点区切り記号としてピリオドが含まれますが、通貨記号は省略されます。

Note

UnitPrice EditItemTemplateには RequiredFieldValidator が含まれていないため、ポストバックをエンスキューし、更新ロジックを開始できます。 ただし、「挿入、更新、削除に関連付けられているイベントを調べる」チュートリアルからコピーした RowUpdating イベント ハンドラーには、UnitPrice が指定されていることを確認する、プログラムによるチェックが含まれています。 このロジックを削除するか、そのままにするか、RequiredFieldValidator を UnitPrice EditItemTemplateに追加してください。

手順 4: データ入力の問題をまとめて示す

5 つの検証コントロールに加えて、ASP.NET には ValidationSummary コントロールが用意されています。これは、無効なデータを検出した検証コントロールの ErrorMessage を表示します。 この概要データは、Web ページ上のテキストとして、またはクライアント側のモーダル メッセージ ボックスを介して表示できます。 検証の問題をまとめて示す、クライアント側のメッセージ ボックスを含むように、このチュートリアルを拡張しましょう。

これを実現するには、ツールボックスからデザイナーに ValidationSummary コントロールをドラッグします。 この検証コントロールの場所は重要ではありません。これは、概要をメッセージ ボックスとして表示するようにそれを構成するだけであるためです。 このコントロールを追加した後、その ShowSummary プロパティfalse に、その ShowMessageBox プロパティtrue に設定します。 これを追加すると、検証エラーがすべてクライアント側のメッセージ ボックスにまとめられます。

検証エラーは、クライアント側のメッセージ ボックスに要約されます

図 11: 検証エラーはクライアント側のメッセージ ボックスにまとめられる (フルサイズの画像を表示するにはこちらをクリックします)

手順 5: DetailsView の InsertItemTemplate に検証コントロールを追加する

このチュートリアルの残りの部分では、DetailsView の挿入インターフェイスに検証コントロールを追加します。 DetailsView のテンプレートに検証コントロールを追加するプロセスは、手順 3 で確認した内容と同じです。そのため、この手順ではそのタスクを簡単に終えることができるでしょう。 GridView の EditItemTemplate で行ったように、その TextBox の ID の名前を、特徴のない TextBox1TextBox2 から InsertProductNameInsertUnitPrice に変更することをお勧めします。

RequiredFieldValidator を ProductName InsertItemTemplateに追加します。 ControlToValidate をこのテンプレートでのその TextBox の IDに設定し、その Text プロパティを "*" に、その ErrorMessageプロパティを "You must provide the product's name" に設定します。

このページでは新しいレコードを追加するときに UnitPrice が必要であるため、RequiredFieldValidator を UnitPrice InsertItemTemplateに追加し、その ControlToValidateText、および ErrorMessage プロパティを適切に設定します。 最後に、UnitPrice InsertItemTemplateに CompareValidator を追加し、ControlToValidateTextErrorMessageTypeOperatorValueToCompareプロパティを構成します。これは、GridView のEditItemTemplateUnitPriceの CompareValidator と同様です。

これらの検証コントロールの追加後は、このシステムへの新しい製品の追加は、その製品の名前が指定されていない場合やその価格が負の数値または不正な形式である場合はできません。

DetailsView の挿入インターフェイスに検証ロジックが追加されました

図 12: 検証ロジックが DetailsView の挿入インターフェイスに追加された (フルサイズの画像を表示するにはこちらをクリックします)

手順 6: 検証コントロールを検証グループに分ける

このページは、GridView の編集インターフェイスに対応する検証コントロールと DetailsView の挿入インターフェイスに対応する検証コントロールという、 2 つの論理的に異なる検証コントロール セットから成ります。 既定では、ポストバックが発生すると、ページ上のすべての検証コントロールがチェックされます。 しかし、レコードの編集時に、DetailsView の挿入インターフェイスの検証コントロールが検証されないようにする必要があります。 図 13 は、有効な値で製品を編集しているときでも [更新] をクリックすると挿入インターフェイスでの名前と価格の値が空白であるために検証エラーが発生するという、現在の問題を示しています。

製品を更新すると、挿入インターフェイスの検証コントロールが起動する

図 13: 製品を更新すると挿入インターフェイスの検証コントロールが実行される (フルサイズの画像を表示するにはこちらをクリックします)

ASP.NET 2.0 での検証コントロールは、それらの ValidationGroup プロパティを使って検証グループに分けることができます。 一連の検証コントロールをグループに関連付けるには、それらの ValidationGroup プロパティを同じ値に設定します。 このチュートリアルでは、GridView の TemplateField での検証コントロールの ValidationGroup プロパティを EditValidationControls に設定し、DetailsView の TemplateField の ValidationGroup プロパティを InsertValidationControls に設定します。 これらの変更は、宣言マークアップで直接行うことや、Designer の編集テンプレート インターフェイスの使用時はプロパティ ウィンドウを使って行うことができます。

検証コントロールに加え、ASP.NET 2.0 での Button および Button 関連コントロールにも、ValidationGroup プロパティが含まれています。 検証グループの検証コントロールは、同じ ValidationGroup プロパティ設定がある Button によってポストバックが引き起こされたときのみ、有効かどうかがチェックされます。 たとえば、DetailsView の [挿入] ボタンで InsertValidationControls 検証グループをトリガーするには、CommandField の ValidationGroup プロパティを InsertValidationControls に設定する必要があります (図 14 を参照)。 また、GridView の CommandField の ValidationGroup プロパティを EditValidationControls に設定します。

DetailsView の CommandField の ValidationGroup プロパティを InsertValidationControls に設定する

図 14: DetailsView の CommandField の ValidationGroup プロパティを InsertValidationControls に設定する (フルサイズの画像を表示するにはこちらをクリックします)

これらの変更後は、DetailsView と GridView の TemplateField と CommandField は次のようになります:

DetailsView の TemplateField と CommandField

<asp:TemplateField HeaderText="ProductName"
  SortExpression="ProductName">
    <InsertItemTemplate>
        <asp:TextBox ID="InsertProductName" runat="server"
         Text='<%# Bind("ProductName") %>'></asp:TextBox>
        <asp:RequiredFieldValidator ID="RequiredFieldValidator2"
          runat="server" ControlToValidate="InsertProductName"
            ErrorMessage="You must provide the product name"
            ValidationGroup="InsertValidationControls">*
        </asp:RequiredFieldValidator>
    </InsertItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="UnitPrice" SortExpression="UnitPrice">
    <InsertItemTemplate>
         <asp:TextBox ID="InsertUnitPrice" runat="server"
           Text='<%# Bind("UnitPrice") %>' Columns="6">
         </asp:TextBox>
         <asp:RequiredFieldValidator ID="RequiredFieldValidator3"
           runat="server" ControlToValidate="InsertUnitPrice"
            ErrorMessage="You must provide the product price"
            ValidationGroup="InsertValidationControls">*
         </asp:RequiredFieldValidator>
        <asp:CompareValidator ID="CompareValidator2" runat="server"
           ControlToValidate="InsertUnitPrice"
           ErrorMessage="The price must be greater than or equal to zero and
                          cannot include the currency symbol"
           Operator="GreaterThanEqual" Type="Currency" ValueToCompare="0"
           ValidationGroup="InsertValidationControls">*
        </asp:CompareValidator>
     </InsertItemTemplate>
 </asp:TemplateField>
<asp:CommandField ShowInsertButton="True"
  ValidationGroup="InsertValidationControls" />

GridView の CommandField と TemplateField

<asp:CommandField ShowEditButton="True" ValidationGroup="EditValidationControls" />
<asp:TemplateField HeaderText="ProductName"
  SortExpression="ProductName">
    <EditItemTemplate>
        <asp:TextBox ID="EditProductName" runat="server"
          Text='<%# Bind("ProductName") %>'>
        </asp:TextBox>
        <asp:RequiredFieldValidator ID="RequiredFieldValidator1"
            runat="server" ControlToValidate="EditProductName"
            ErrorMessage="You must provide the product name"
            ValidationGroup="EditValidationControls">*
        </asp:RequiredFieldValidator>
    </EditItemTemplate>
    <ItemTemplate>
        <asp:Label ID="Label1" runat="server"
          Text='<%# Bind("ProductName") %>'></asp:Label>
    </ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="UnitPrice" SortExpression="UnitPrice">
    <EditItemTemplate>
        <asp:TextBox ID="EditUnitPrice" runat="server"
          Text='<%# Bind("UnitPrice", "{0:n2}") %>' Columns="6"></asp:TextBox>
        <asp:CompareValidator ID="CompareValidator1" runat="server"
            ControlToValidate="EditUnitPrice"
            ErrorMessage="The price must be greater than or equal to zero and
                           cannot include the currency symbol"
            Operator="GreaterThanEqual" Type="Currency"
            ValueToCompare="0"
            ValidationGroup="EditValidationControls">*
        </asp:CompareValidator>
    </EditItemTemplate>
    <ItemTemplate>
        <asp:Label ID="Label2" runat="server"
            Text='<%# Bind("UnitPrice", "{0:c}") %>'>
        </asp:Label>
    </ItemTemplate>
</asp:TemplateField>

この時点で、編集固有の検証コントロールは GridView の [更新] ボタンがクリックされたときのみ実行され、挿入固有の検証コントロールは DetailsView の [挿入] ボタンがクリックされたときのみ実行されるようになっており、図 13 で示されている問題が解決されています。 ただし、この変更により、無効なデータを入力しても ValidationSummary コントロールが表示されなくなります。 ValidationSummary コントロールには ValidationGroup プロパティも含まれており、その検証グループ内の検証コントロールの概要情報のみが表示されます。 そのため、このページには 2 つの検証コントロールが必要です。1 つは InsertValidationControls 検証グループ用で、1 つは EditValidationControls 検証グループ用です。

<asp:ValidationSummary ID="ValidationSummary1" runat="server"
    ShowMessageBox="True" ShowSummary="False"
    ValidationGroup="EditValidationControls" />
<asp:ValidationSummary ID="ValidationSummary2" runat="server"
    ShowMessageBox="True" ShowSummary="False"
    ValidationGroup="InsertValidationControls" />

これを追加すれば、このチュートリアルは完了です!

まとめ

BoundField では挿入および編集インターフェイスを両方提供できますが、それらのインターフェイスはカスタマイズできません。 一般的には、必要な入力を有効な形式で入力できるように、検証コントロールを編集および挿入インターフェイスに追加します。 これを実現するには、BoundField を TemplateField に変換し、検証コントロールを適切なテンプレートに追加する必要があります。 このチュートリアルでは、「挿入、更新、削除に関連付けられているイベントを調べる」チュートリアルにある例を拡張して、DetailsView の挿入インターフェイスと GridView の編集インターフェイスの両方に検証コントロールを追加しました。 さらに、ValidationSummary コントロールを使って検証の概要情報を表示する方法と、ページ上の検証コントロールを個別の検証グループに分ける方法を確認しました。

このチュートリアルで説明したとおり、TemplateField を使うと、編集および挿入インターフェイスを拡張して検証コントロールを含めることができます。 TemplateField を拡張してその他の入力 Web コントロールを含めることもできます。これにより、TextBox をより適切な Web コントロールに置き換えることができます。 次のチュートリアルでは、TextBox コントロールをデータ バインド済み DropDownList コントロールに置き換える方法について説明します。このコントロールは、外部キー (Products テーブル内の CategoryIDSupplierID など) を編集する場合に最適です。

プログラミングに満足!

著者について

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

特別な感謝

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