はじめに
WPFにはDataAnnotationsという仕組みがあって、入力値の検証ができる属性が実装されています。プロパティに属性をつけて、ユーザー入力に対して検証ルールに合致しなければ、エラーを通知するというものです。本記事では、どんな検証ができるのか紹介します。
#まずは、DataAnnotationsを参照設定に加えます。
using System.ComponentModel.DataAnnotations;
#プロパティの定義と初期化
ReactivePropertyのSetValidateAttributeメソッドをつかいます。
public class SampleViewModel: ViewModelBase
{
public SampleViewModel()
{
// ユーザーからの入力を受けるプロパティ
this.Input = new ReactiveProperty<string>()
.SetValidateAttribute(() => this.Input)
.AddTo(this.disposedValue);
}
public ReactiveProperty<string> Input { get; }
}
#さまざまな入力値検証
Required
必須入力。入力されているかどうかをチェックします。
[Required()]
public ReactiveProperty<string> Input { get; }
引数にErrorMessageを指定すれば、任意のメッセージを表示することができます。
[Required(ErrorMessage = "何か入力してください。")]
public ReactiveProperty<string> Input { get; }
StringLength
文字列長。引数に文字数を設定。入力値が設定した文字数以内かチェックします。
[StringLength(10)]
public ReactiveProperty<string> Input { get; }
Range
数値の範囲。引数に最小値と最大値を設定する。入力値が最小値~最大値の範囲内かどうかをチェックします。
[Range(0,5)]
public ReactiveProperty<string> Input { get; }
[Range(typeof(DateTime),"2020/10/1", "2020/10/5")]
public ReactiveProperty<string> Input { get; }
##RegularExpression
正規表現。引数に正規表現のルールを設定する。入力値が正規表現に一致するかチェックしします。
[RegularExpression("[a-d]+")]
public ReactiveProperty<string> Input { get; }
CustomValidation
カスタム検証。引数にクラスの型とクラスが持っているメソッド名を指定する。メソッド内で任意の条件を実装することが可能。
[CustomValidation(typeof(CustomValidateMethods), "Test")]
public ReactiveProperty<string> Input { get; }
public static class CustomValidateMethods
{
public static ValidationResult Test(object value, ValidationContext context)
{
var input = value?.ToString() ?? string.Empty;
// 何らかの条件
var result = input == "123";
return result ? ValidationResult.Success : new ValidationResult("エラーです。");
}
}
ValidationAttribute属性を継承
基底クラスのValidationAttributeクラスを継承すると、自前の検証クラスを作ることができます。
[MyValidation("abc","abcって入力してください。")]
public ReactiveProperty<string> Input { get; }
[AttributeUsage(AttributeTargets.Property)]
public class MyValidationAttribute: ValidationAttribute
{
public string Answer { get; }
public MyValidationAttribute(string ansewer, string errorMessage = "")
{
this.Answer = ansewer;
if (!string.IsNullOrEmpty(errorMessage)) this.ErrorMessage = errorMessage;
}
protected override ValidationResult IsValid(object value, ValidationContext context)
{
var input = value?.ToString() ?? string.Empty;
// 何らかの条件
var result = input == this.Answer;
return result ? ValidationResult.Success : new ValidationResult(this.ErrorMessage);
}
}
#【おまけ】ボタンとの連携
入力値の検証をボタンの活性・非活性を組み合わせることができます。
エラーがなくなるまで、ボタンは押させない!
public ReactiveCommand Execute { get; }
this.Execute = new[]
{
this.Input.ObserveHasErrors
}
.CombineLatestValuesAreAllFalse()
.ToReactiveCommand()
.AddTo(this.disposedValue);
#最後に
他にもいろいろValidationの属性はあるかと思いますが、とりあえずここまで。
以上。