15

私は WPF 検証システムに非常に失望しています。ともかく!「ボタン」をクリックして完全なフォームを検証するにはどうすればよいですか?

何らかの理由で、WPF のすべてが非常に複雑です。ASP.NET では 1 行のコードで検証を実行できますが、WPF では 10 ~ 20 行のコードが必要です!!

これは、独自の ValidationEngine フレームワークを使用して実行できます。

Customer customer = new Customer();
customer.FirstName = "John";
customer.LastName = String.Empty;

ValidationEngine.Validate(customer);

if (customer.BrokenRules.Count > 0)
{
   // do something display the broken rules! 
}
4

5 に答える 5

27

WPFアプリケーションは、入力されたデータが有効でない場合、フォームを送信するためのボタンを無効にする必要があります。これを実現するには、Bindings withを使用して、ビジネスオブジェクトにIDataErrorInfoインターフェイスを実装します。エラーが発生した場合に個々のコントロールの外観をカスタマイズするには、を設定します。ValidatesOnDataErrors=trueValidation.ErrorTemplate

XAML:

<Window x:Class="Example.CustomerWindow" ...>
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Save"
                        CanExecute="SaveCanExecute"
                        Executed="SaveExecuted" />
    </Window.CommandBindings>
    <StackPanel>
        <TextBox Text="{Binding FirstName, ValidatesOnDataErrors=true, UpdateSourceTrigger=PropertyChanged}" />
        <TextBox Text="{Binding LastName, ValidatesOnDataErrors=true, UpdateSourceTrigger=PropertyChanged}" />
        <Button Command="ApplicationCommands.Save" IsDefault="True">Save</Button>
        <TextBlock Text="{Binding Error}"/>
    </StackPanel>
</Window>

これにより、顧客の名前と名前を編集できるWindow2つのesが作成されます。TextBox[保存]ボタンは、検証エラーが発生していない場合にのみ有効になります。ボタンのTextBlock下には現在のエラーが表示されるため、ユーザーは何が起きているかを知ることができます。

デフォルトErrorTemplateは、エラーのあるコントロールの周りの細い赤い境界線です。それが視覚的な概念に合わない場合は、CodeProjectのWindows Presentation Foundationでの検証の記事を参照して、それについて何ができるかを詳しく調べてください。

ウィンドウを実際に機能させるには、ウィンドウと顧客に少しインフラストラクチャが必要です。

コードビハインド

// The CustomerWindow class receives the Customer to display
// and manages the Save command
public class CustomerWindow : Window
{
    private Customer CurrentCustomer;
    public CustomerWindow(Customer c) 
    {
        // store the customer for the bindings
        DataContext = CurrentCustomer = c;
        InitializeComponent();
    }

    private void SaveCanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = ValidationEngine.Validate(CurrentCustomer);
    }

    private void SaveExecuted(object sender, ExecutedRoutedEventArgs e) 
    {
        CurrentCustomer.Save();
    }
}

public class Customer : IDataErrorInfo, INotifyPropertyChanged
{
    // holds the actual value of FirstName
    private string FirstNameBackingStore;
    // the accessor for FirstName. Only accepts valid values.
    public string FirstName {
        get { return FirstNameBackingStore; }
        set {
            FirstNameBackingStore = value;
            ValidationEngine.Validate(this);
            OnPropertyChanged("FirstName");
        }
    }
    // similar for LastName        

    string IDataErrorInfo.Error {
        get { return String.Join("\n", BrokenRules.Values); }
    }

    string IDataErrorInfo.this[string columnName]
    {
        get { return BrokenRules[columnName]; }
    }
}

明らかな改善は、実装をクラス階層の上位に移動することです。これは、ビジネスオブジェクトにはIDataErrorInfo依存せず、に依存するためです。ValidationEngine

これは確かにあなたが提供した単純な例よりも多くのコードですが、妥当性をチェックするだけではなく、かなり多くの機能も備えています。これにより、検証の問題についてユーザーにきめ細かく自動的に更新された表示が提供され、ユーザーが無効なデータを入力しようとしている限り、[保存]ボタンが自動的に無効になります。

于 2008-10-08T11:50:38.813 に答える
2

ビジネス オブジェクトの IDataErrorInfo インターフェイスを確認することをお勧めします。こちらの記事もご覧ください: Self Validating Text Box

于 2008-09-19T19:49:41.953 に答える
1

WPF アプリケーション フレームワーク (WAF)のBookLibraryサンプル アプリケーションに興味があるかもしれません。WPF で検証を使用する方法と、検証エラーが存在する場合に [保存] ボタンを制御する方法を示します。

于 2010-08-16T17:16:46.273 に答える
1

ValidatesOnDataError は、ビュー モデルに対してビジネス ルールを検証するために使用され、バインディングが成功した場合にのみ検証されます。

ValidatesOnExceptions を ValidatesOnDataError と一緒に適用して、データ型の不一致のために wpf がバインドを実行できないシナリオを処理する必要があります。ビュー モデルで TextBox を Age (整数) プロパティにバインドするとします。

<TextBox Text="{Binding Age, ValidatesOnDataErrors=true, UpdateSourceTrigger=PropertyChanged}" />

ユーザーが年齢として数字ではなくアルファベットを入力して無効なエントリを入力した場合、xyz など、 wpfデータバインディングは値を無視します。

<TextBox Text="{Binding Age, ValidatesOnDataErrors=true, ValidatesOnExceptions="True", UpdateSourceTrigger=PropertyChanged}" />

ValidatesOnException は、ExceptionValidationRule を使用してバインド エラーにデフォルトの例外処理を使用します。上記の構文は、次の短い形式です。

<TextBox>
    <TextBox.Text>
        <Binding Path="Age" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
            <Binding.ValidationRules>
                  <ExceptionValidationRule />
             </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

次の例では、ValidationRule から派生させて Validate メソッド NumericRule を実装することにより、ユーザー入力に対して検証する独自のルールを定義できます。

<TextBox.Text>
 <Binding Path="Age" ValidatesOnDataErrors="True">
   <Binding.ValidationRules>
        <rules:NumericRule />
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>

検証ルールは一般的であり、ビジネスに結び付けられないようにする必要があります。後者は IDataErrorInfo および ValidatesOnDataError によって達成されるからです。

上記の構文は、私たちが持っている 1 行のバインド構文に比べてかなり厄介です。ValidationRule を添付プロパティとして実装することで、構文を改善することができます。ここで確認できます。

于 2010-11-24T05:34:08.370 に答える
0

あなたの問題の説明は私には少しあいまいです。つまり、あなたの困難が何であるか正確にはわかりません。DataContext が、顧客インスタンスを表すプロパティを持つある種のプレゼンターまたはコントローラーであり、ValidateCommand が ICommand 型のプロパティであると仮定します。

  <StackPanel>  
    <TextBox Text="{Binding CurrentCustomer.FirstName}" />
    <TextBox Text="{Binding CurrentCustomer.LastName}" />
    <Button Content="Validate" 
            Command="{Binding ValidateCommand}"
            CommandParameter="{Binding CurrentCustomer}" />
    <ItemsControl ItemsSource="{Binding CurrentCustomer.BrokenRules}" />
  </StackPanel>

もちろん、この XAML は非常に単純化されており、それを行う方法は他にもあります。現在 WPF に深く関わっている Web 開発者として、このようなほとんどのタスクは WPF の方がはるかに簡単であることがわかります。

于 2008-10-01T13:45:57.083 に答える