Windows Phone 7用のアプリケーションを最初から最後まで作成します。 パート14.入力データの検証

前の部分



可能性のあるエラーを防ぐために、アプリケーションはすべてのユーザー入力をチェックする必要があります。



このパートでは、次のことを学習します。

検証



通常、ユーザーが入力できるデータを制限すると便利です。 ユーザー入力を制限できる2つの簡単な方法を次に示します。

これらの制限があっても、原則として、他の理由で正しくフォーマットされていないか無効な値を入力できます。



検証要件は異なる場合がありますが、原則として、データをチェックして、誤った値が保存されないようにします。 この場合、データウェアハウスに直接バインドするよりも、ユーザーインターフェイスを一時オブジェクトにバインドする方が便利です。 たとえば、Fuel Trackerアプリケーションでは、ユーザーが[保存]ボタンをクリックするまで、新しい給油データはFillupHistoryコレクションに追加されません。 ただし、保存する前に、ユーザーはデータを確認して、正確に指定されていることを確認できます。 ユーザーが[保存]ボタンをクリックすると、検証コードは最後のエラーチェックを1つ実行し、ユーザーに問題を警告します。



次のコードは、 Fillupクラスで使用される単純な検証メソッドを示しています。

public IEnumerable < string > Validate() { if (OdometerReading <= 0) yield return "The odometer value must be greater than zero." ; if (DistanceDriven <= 0) yield return "The odometer value must be greater than the previous value." ; if (FuelQuantity <= 0) yield return "The fuel quantity must be greater than zero." ; if (PricePerFuelUnit <= 0) yield return "The fuel price must be greater than zero." ; } * This source code was highlighted with Source Code Highlighter .



  1. public IEnumerable < string > Validate() { if (OdometerReading <= 0) yield return "The odometer value must be greater than zero." ; if (DistanceDriven <= 0) yield return "The odometer value must be greater than the previous value." ; if (FuelQuantity <= 0) yield return "The fuel quantity must be greater than zero." ; if (PricePerFuelUnit <= 0) yield return "The fuel price must be greater than zero." ; } * This source code was highlighted with Source Code Highlighter .



  2. public IEnumerable < string > Validate() { if (OdometerReading <= 0) yield return "The odometer value must be greater than zero." ; if (DistanceDriven <= 0) yield return "The odometer value must be greater than the previous value." ; if (FuelQuantity <= 0) yield return "The fuel quantity must be greater than zero." ; if (PricePerFuelUnit <= 0) yield return "The fuel price must be greater than zero." ; } * This source code was highlighted with Source Code Highlighter .



  3. public IEnumerable < string > Validate() { if (OdometerReading <= 0) yield return "The odometer value must be greater than zero." ; if (DistanceDriven <= 0) yield return "The odometer value must be greater than the previous value." ; if (FuelQuantity <= 0) yield return "The fuel quantity must be greater than zero." ; if (PricePerFuelUnit <= 0) yield return "The fuel price must be greater than zero." ; } * This source code was highlighted with Source Code Highlighter .



  4. public IEnumerable < string > Validate() { if (OdometerReading <= 0) yield return "The odometer value must be greater than zero." ; if (DistanceDriven <= 0) yield return "The odometer value must be greater than the previous value." ; if (FuelQuantity <= 0) yield return "The fuel quantity must be greater than zero." ; if (PricePerFuelUnit <= 0) yield return "The fuel price must be greater than zero." ; } * This source code was highlighted with Source Code Highlighter .



  5. public IEnumerable < string > Validate() { if (OdometerReading <= 0) yield return "The odometer value must be greater than zero." ; if (DistanceDriven <= 0) yield return "The odometer value must be greater than the previous value." ; if (FuelQuantity <= 0) yield return "The fuel quantity must be greater than zero." ; if (PricePerFuelUnit <= 0) yield return "The fuel price must be greater than zero." ; } * This source code was highlighted with Source Code Highlighter .



  6. public IEnumerable < string > Validate() { if (OdometerReading <= 0) yield return "The odometer value must be greater than zero." ; if (DistanceDriven <= 0) yield return "The odometer value must be greater than the previous value." ; if (FuelQuantity <= 0) yield return "The fuel quantity must be greater than zero." ; if (PricePerFuelUnit <= 0) yield return "The fuel price must be greater than zero." ; } * This source code was highlighted with Source Code Highlighter .



  7. public IEnumerable < string > Validate() { if (OdometerReading <= 0) yield return "The odometer value must be greater than zero." ; if (DistanceDriven <= 0) yield return "The odometer value must be greater than the previous value." ; if (FuelQuantity <= 0) yield return "The fuel quantity must be greater than zero." ; if (PricePerFuelUnit <= 0) yield return "The fuel price must be greater than zero." ; } * This source code was highlighted with Source Code Highlighter .



  8. public IEnumerable < string > Validate() { if (OdometerReading <= 0) yield return "The odometer value must be greater than zero." ; if (DistanceDriven <= 0) yield return "The odometer value must be greater than the previous value." ; if (FuelQuantity <= 0) yield return "The fuel quantity must be greater than zero." ; if (PricePerFuelUnit <= 0) yield return "The fuel price must be greater than zero." ; } * This source code was highlighted with Source Code Highlighter .



  9. public IEnumerable < string > Validate() { if (OdometerReading <= 0) yield return "The odometer value must be greater than zero." ; if (DistanceDriven <= 0) yield return "The odometer value must be greater than the previous value." ; if (FuelQuantity <= 0) yield return "The fuel quantity must be greater than zero." ; if (PricePerFuelUnit <= 0) yield return "The fuel price must be greater than zero." ; } * This source code was highlighted with Source Code Highlighter .



  10. public IEnumerable < string > Validate() { if (OdometerReading <= 0) yield return "The odometer value must be greater than zero." ; if (DistanceDriven <= 0) yield return "The odometer value must be greater than the previous value." ; if (FuelQuantity <= 0) yield return "The fuel quantity must be greater than zero." ; if (PricePerFuelUnit <= 0) yield return "The fuel price must be greater than zero." ; } * This source code was highlighted with Source Code Highlighter .



  11. public IEnumerable < string > Validate() { if (OdometerReading <= 0) yield return "The odometer value must be greater than zero." ; if (DistanceDriven <= 0) yield return "The odometer value must be greater than the previous value." ; if (FuelQuantity <= 0) yield return "The fuel quantity must be greater than zero." ; if (PricePerFuelUnit <= 0) yield return "The fuel price must be greater than zero." ; } * This source code was highlighted with Source Code Highlighter .



public IEnumerable < string > Validate() { if (OdometerReading <= 0) yield return "The odometer value must be greater than zero." ; if (DistanceDriven <= 0) yield return "The odometer value must be greater than the previous value." ; if (FuelQuantity <= 0) yield return "The fuel quantity must be greater than zero." ; if (PricePerFuelUnit <= 0) yield return "The fuel price must be greater than zero." ; } * This source code was highlighted with Source Code Highlighter .





次の図は、走行距離計の読み取り値が以前の値よりも小さいときに[保存]ボタンをクリックしたときに表示されるメッセージの例を示しています。



画像



このコードは、 Fillupプロパティの値を単純にチェックし、無効な値についてはエラーメッセージを返します。 ただし、ユーザーがすべてのチェック値を指定するわけではないため、事前に初期化を行う必要があります。 特に、距離は、 Fillup.OdometerReadingの値を以前の走行距離計の読み取り値と比較して計算する必要があります。 ただし、現在のFillupオブジェクト前の値にアクセスできないため、このアクションは、次のコードフラグメントに示すように、 CarDataStore.SaveFillupメソッドによって実行されます。





  1. public static SaveResult SaveFillup(Fillup fillup、Action errorCallback)
  2. {
  3. var lastReading =
  4. Car.FillupHistory.Count> 0?
  5. Car.FillupHistory.First()。OdometerReading:
  6. Car.InitialOdometerReading;
  7. fillup.DistanceDriven = fillup.OdometerReading-lastReading;
  8. var saveResult = new SaveResult();
  9. var validationResults = fillup.Validate();
  10. if (validationResults.Count()> 0)
  11. {
  12. saveResult.SaveSuccessful = false ;
  13. saveResult.ErrorMessages = validationResults;
  14. }
  15. 他に
  16. {
  17. Car.FillupHistory.Insert(0、fillup);
  18. saveResult.SaveSuccessful = true ;
  19. SaveCar( デリゲート {
  20. saveResult.SaveSuccessful = false ;
  21. errorCallback(); });
  22. }
  23. return saveResult;
  24. }
*このソースコードは、 ソースコードハイライターで強調表示されました。


CarDataStore.SaveFillupメソッドは、保存用のFillupオブジェクトとエラー処理用のActionデリゲートを受け入れます。 このメソッドは、現在の走行距離計の読み取り値から以前の読み取り値を減算し、 Fillup.DistanceDrivenプロパティに結果を保存することから始まります。これにより、このクラスでミルクチェックを実行できます。 次に、 SaveFillupメソッドはFillup.Validateメソッドを呼び出し、結果を特別なSaveResultオブジェクトに保存し、呼び出し元のメソッドに返します。 検証エラーが発生しない場合、 SaveFillupメソッドは給油と車両データを保存します。 最後に、 SaveFillupメソッドはSaveResultオブジェクトを返します。



注:

Silverlight for Windows Phoneは、Binding.ValidatesOnExceptionsプロパティを介して基本的なバインディング対応検証を提供します。 ただし、Windows Phoneのコントロールバージョンは検証パターンを提供しません。 検証をサポートするための1つのオプションは、コントロールに独自の検証テンプレートを提供することです。



次のコードスニペットは、ユーザーが給油情報ページの[保存]ボタンをクリックしたときに何が起こるかを示しています。





  1. private void SaveButton_Click( オブジェクト送信者、 EventArgs e)
  2. {
  3. CommitTextBoxes();
  4. SaveResult結果= CarDataStore.SaveFillup(currentFillup、
  5. デリゲート {
  6. MessageBox.Show( 「携帯電話に十分なスペースがありません」 +
  7. 「記入データを保存します。空き容量を増やして、もう一度お試しください。」
  8. "警告" 、MessageBoxButton.OK);
  9. });
  10. if (result.SaveSuccessful)
  11. {
  12. Microsoft.Phone.Shell.PhoneApplicationService.Current
  13. .State [ "FillupSaved" ] = true ;
  14. cacheChanges = false ;
  15. NavigationService.GoBack();
  16. }
  17. 他に
  18. {
  19. string errorMessages = String .Join(
  20. Environment.NewLine + Environment.NewLine、
  21. result.ErrorMessages.ToArray());
  22. if (! String .IsNullOrEmpty(errorMessages))
  23. {
  24. MessageBox.Show(errorMessages、
  25. 「警告:無効な値」 、MessageBoxButton.OK);
  26. }
  27. }
  28. }
*このソースコードは、 ソースコードハイライターで強調表示されました。


このコードは、 前述のようにSaveFillupメソッドを呼び出し、コールバックエラーを渡します。 このデリゲートは、メッセージボックスにエラー状態を表示するだけです。 次に、メソッドは検証エラーがあるかどうかを確認し、イベントハンドラーはそれらをメッセージボックスに表示します。



保存が成功すると、 SaveButton_Clickメソッドはアプリケーションレベルのステータスディクショナリを使用して、新しい給油情報が保存されたことを示す値を保存します。 次に、このメソッドはジャンプしますが、最初に「非アクティブ化後のアプリケーションの復元」で説明したように、キャッシュを防ぐためにフラグを設定します。 遷移の完了後、 SummaryPageが値が状態ディクショナリに格納されていることを検出すると、ページに要約情報の最初の段落が表示されるため、ユーザーは燃料補給の結果をすぐに見ることができます。 それ以外の場合、 FillupPageに切り替える前に表示されたサマリーアイテムに応じて、 SummaryPageが自動的に表示されます。



ここでは1つの検証方法についてのみ説明しますが、さらに多くの検証方法があります。



戻るときに保存されていない変更を確認します



デフォルトでは、戻るボタンを押すと元に戻ります。 保存されていない変更を含むデータ入力ページがあり、ユーザーが「戻る」ボタンをクリックした場合、ユーザーにこれを通知する必要があります。 この動作を実装するには、PhoneApplicationPage.OnBackKeyPressメソッドをオーバーロードし、保存されていない変更を確認します。 保存されていない変更がある場合は、これについてユーザーに通知し、場合によっては移行をキャンセルできます。



認定要件:

一貫したユーザーエクスペリエンスをサポートするには、戻るボタンはアプリケーションに戻るためにのみ使用する必要があります。



この要件を満たすために、OnBackKeyPressオーバーロードを使用して後方遷移を取り消し、戻るボタンの動作を完全に変更しないでください。 ユーザーがデータの削除を確認するのを待つなど、必要なナビゲーション関連の操作を実行するために、逆方向ナビゲーションをキャンセルする機能が提供されます。

Fuel Trackerには、データ入力用の2つのページ、 CarDetailsPageFillupPageがあります。 これらのページに保存されていない変更があり、ユーザーが[戻る]をクリックすると、確認を要求するメッセージが画面に表示されます。 次の画像は、確認が必要なメッセージの例を示しています。



画像



インターフェース設計の推奨事項:

データを上書きまたは削除する、または元に戻せないアプリケーションアクションには、[キャンセル]ボタンが必要です。

次のコードスニペットは、Fuel TrackerアプリケーションがPhoneApplicationPage.OnBackKeyPressメソッドをオーバーロードして、未保存のデータがある場合に確認が必要なメッセージを表示する方法を示しています。





  1. 保護された オーバーライド void OnBackKeyPress(
  2. System.ComponentModel.CancelEventArgs e)
  3. {
  4. base .OnBackKeyPress(e);
  5. //変更がない場合は、何もしません。
  6. if (!hasUnsavedChanges) return ;
  7. var result = MessageBox.Show( "破棄しようとしています" +
  8. 「変更します。続行しますか?」「警告」 、MessageBoxButton.OKCancel);
  9. if (結果== MessageBoxResult.OK)
  10. {
  11. //通常のナビゲーション。 廃棄を処理する必要はありません。
  12. //したがって、cacheChangesフラグを設定し、現在のキャッシュをクリアします。
  13. cacheChanges = false ;
  14. this .State.Remove(CURRENT_FILLUP_KEY);
  15. }
  16. 他に
  17. {
  18. //後方ナビゲーションをキャンセルします。
  19. e.Cancel = true ;
  20. }
  21. }
*このソースコードは、 ソースコードハイライターで強調表示されました。


このメソッドは、最初に未保存の変更があるかどうかを確認します。 存在しない場合、メソッドは何も実行せず、自動的に戻ります。 それ以外の場合、メソッドは確認を要求するメッセージを表示します。 ユーザーが「OK」をクリックして元の遷移を続行する場合、ページは廃棄を処理する必要がないため、メソッドはいくつかのアクションを実行し、元の遷移を実行します。 ユーザーが[キャンセル]をクリックすると、元に戻すことはキャンセルされます。



次の部分へのリンクがあります。

前編



All Articles