1

そのため、私はMVVMを初めて使用し、ユーザー入力の検証に関するいくつかの問題に苦労しています。WPF には「魔法」のように機能する組み込み機能がいくつかありますが、一般的に、「魔法」が良くないことはわかっています。

例:TextBoxタイプが のプロパティに をバインドしdouble、ユーザーがその に「hello」と入力するとTextBox、WPF は の周りに赤い境界線を自動的に表示TextBoxし、入力が無効であることをユーザーに通知します。

これはすべてうまくいっていますが、「魔法」のように見えます。経験豊富な開発者から、似たような WPF ビルダーとアプリ ビルダーはあまりにも多くの制御を必要としていると言われました。彼は、Web 開発では、View は Property がどのタイプであるかを認識できないと述べました。それは私には理にかなっています。したがって、これは私の一般的な質問につながります-WPFビューはプロパティタイプを理解する必要がありますか? - 代わりに Property 型を として宣言した場合、ビューを完全に制御stringできます。WPF の「スマート」「マジック」を回避する必要はありません。TextBox

私の質問を言い換える別の方法は -モデルまたはビューモデルでプロパティ型を宣言する必要がありますか?

モデルで Property 型を として宣言し、ViewModel で として宣言する場合、モデルで解析する必要があることdoubleを理解しています。string私が調べた MVVM アプリケーションのほとんどの例では、Property 型はアプリケーション全体で似ていますが、何を処理しているのかを理解していない「愚かな」ビューの方がはるかに優れていると思います。

私の例に戻ります:プロパティが として宣言されているString場合、入力に必要な形式を完全に制御し、無効な入力をすべて一緒に防ぐことができます。これは、 WPF を信頼するよりもはるかに優れたソリューションのようTextBoxです。

4

3 に答える 3

5

はい、WPFのその機能は「とてもいい」と思います:)

WPF には、データ層と UI 層の 2 つの層があります。

データレイヤーにはデータが含まれています。データに数値が含まれている場合は、文字列データ型ではなく、数値データ型にする必要があります。

UI レイヤー (XAML) は、ユーザーがデータ レイヤーを簡単に操作できるように、データに使いやすいインターフェイスを提供することだけを目的としています。たとえば、数値を含むデータ レイヤーがあり、ユーザーがその値を編集できるようにする場合は、TextBox.

UI レイヤーが を使用してデータを表示しているという理由だけで、数値ではなく文字列を使用するようにデータ レイヤーを強制すると、TextBoxUI にアプリケーションを制御させることになり、これは WPF の動作方法ではありません。さらに、このように 2 つのレイヤーを一緒にブレンドすると、将来のメンテナンスが非常に難しくなります。たとえば、TextBoxNumericUpDownUI コントロールに変更するとどうなるでしょうか。次に、データ レイヤーを変更して UI を変更する必要があります。

あなたの特定の例に関して、TextBoxa を double にバインドして「hello」のような文字列を入力すると、実際に発生するのは、WPF が double 値を文字列値に設定しようとし、例外がスローされることです。

その例外が原因で、TextBox特別な処理ではなく、 の周りに赤い境界線が表示され、エラー メッセージが表示されます。double プロパティのセッターで例外をスローするのと同じくらい簡単で、同じことが起こります。

私はそれを「魔法」とは呼びません。ただの例外処理です:)

ただし、入力を検証する必要があるときにいつでも例外をスローする必要がないように、WPF には、例外をスローせずにプロパティを検証するために使用できるIDataErrorInfoインターフェイスが用意されています。UI は、例外に反応するのと同じ方法で、このインターフェイスで発生したエラーに反応します。

于 2013-02-26T14:58:08.960 に答える
2

はい、そうすべきです。

Karl Shifflett の素晴らしい記事があります。入力検証 – UI 例外とモデル検証エラー

解決策は、無効な入力を検出することです。ユーザーが無効なデータ型を入力すると、データ バインディング パイプラインは例外をスローします。それが発生したら、Viewで処理し、 ViewModelにエラー メッセージを追加して、必要なときに使用できるようにします。

WPF はデフォルトでそのデータ バインディング例外を飲み込みますが、 ViewクラスのLoadedイベントにハンドラーを追加できます。

_errorEventRoutedEventHandler = new RoutedEventHandler(ExceptionValidationErrorHandler);
this.AddHandler(System.Windows.Controls.Validation.ErrorEvent, _errorEventRoutedEventHandler, true);

ハンドラーを実装する

private void ExceptionValidationErrorHandler(object sender, RoutedEventArgs e)
{
    // Add logic to handle this invalid data type exception. 
    // Add error messages to viewmodel, show notification dialog, etc
    ...
}

XAML バインディングのNotifyOnValidationErrorValidatesOnDataErrorsValidatesOnExceptionsでこれらのプロパティを true に設定します。

Text="{Binding UnitPrice, StringFormat=c, NotifyOnValidationError=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}"

それでおしまい。

于 2013-02-26T14:50:01.320 に答える
1

強い型の言語を使用しているので、遅かれ早かれ検証が必要になります。すでに手元にある検証の形式を使用しないことで何を達成したいかわかりません。無効な入力が与えられたときに、ビューを変更して、好きなことを実行できることを忘れないでください。(@Rachelによって説明されているように)例外をスローしたくない場合は、文字列プロパティを使用すると例外が防止される可能性があります。

宣言

データベースに接続されているプロパティは、モデルで宣言されています。モデルをユーザーフレンドリーなものに変換するために必要なプロパティは、ViewModelで宣言されます。たとえば、データベースに格納されている値( valueA )があります。valueAは、ユーザーが使用できる2つの入力フィールド(valueBvalueC)を使用して計算されます。この場合、 valueAはモデルで宣言されますが、valueBvalueCはデータベースに格納する必要がないため、ViewModelでのみ宣言されます。(技術的には、3つすべてがViewModelで使用できますが、valueAのみがモデルで宣言されます)

私がそれを理解する方法:

  • モデルには、データベースに保存されているプロパティがあります
  • ViewModelモデルをユーザーが処理できるものに変換します(その逆も同様です)。
  • ビューは、多かれ少なかれ「ViewModelの入力領域」であり、ユーザーはグラフィックの使用によって支援されます。
于 2013-02-26T14:55:11.637 に答える